Aptly Cards API

The Cards API from Aptly — 6 operation(s) for cards.

Operations 9

POST /api/board/{boardId}/list List cards #
GET /api/board/{boardId} List cards (deprecated) #
POST /api/board/{boardId} Create or update a card #
GET /api/board/{boardId}/{cardId} Get a card #
DELETE /api/board/{boardId}/{cardId} Archive a card #
GET /api/board/{boardId}/{cardId}/comments List comments on a card #
GET /api/board/{boardId}/{cardId}/contacts List contacts linked to a card #
POST /api/board/{boardId}/{cardId}/comment Add or update a comment #
POST /api/board/{boardId}/{cardId}/file Upload a file to a card #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/aptly:aptly-cards-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

aptly-cards-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Aptly Cards API
  version: '1.1'
  description: 'The Aptly API lets external systems work with boards, contacts, inboxes,

    tasks, files, and other Aptly resources.


    Most endpoints accept an API key in the `x-token` header. Some endpoints

    also accept a delegate token or partner bearer token, as shown in each

    operation''s security requirements, and explicitly public endpoints require

    no credential. API keys are scoped to a company and may be restricted to

    specific boards and read, insert, or update permissions; requests outside

    those restrictions receive a 403 `FORBIDDEN` response.'
servers:
- url: https://core-api.getaptly.com
  description: Production
security:
- ApiKeyHeader: []
tags:
- name: Cards
paths:
  /api/board/{boardId}/list:
    post:
      summary: List cards
      description: 'Returns a paginated list of cards on the board.


        Field values are keyed by field UUID — use the schema endpoint to map keys to labels.

        Money fields are returned as `{ amount, currency }` where `amount` is a decimal.


        All filter params are optional and ANDed together.


        Supply segmentId OR rules (a JSON array), never both. Rules use the existing saved-segment format. Invalid rules fail with 400; missing, private-to-another-user, archived, or wrong-board segments return 404.


        Auth: API key, delegate token (boards:* or boards:{boardId} read scope), or partner bearer token with board-admin. Mobile tokens are not accepted. Keys/delegates require API-enabled boards; partner access retains its existing API-enabled bypass. API keys/partners may supply userId for an active company member; delegates can only use their token user. Without userId only public segments are visible. Public means company-shared.


        This /list POST performs no writes and does not change POST /api/board/{boardId}, which creates/updates cards. Rules are ANDed. Relative dates are evaluated on each request. See the Board segments guide for values, field comparisons, business-hours rules, and examples.'
      operationId: listBoardCards
      tags:
      - Cards
      security:
      - ApiKeyHeader: []
      - DelegateToken: []
      - PartnerBearer: []
      parameters:
      - name: boardId
        in: path
        required: true
        schema:
          type: string
        description: The board's UUID.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BoardCardListRequest'
            examples:
              segment:
                summary: Saved segment
                value:
                  page: 0
                  pageSize: 20
                  segmentId: SEGMENT_ID
                  userId: USER_ID
              adhoc:
                summary: My cards in a stage updated within 24 hours
                value:
                  page: 0
                  userId: USER_ID
                  rules:
                  - fieldUuid: assignee
                    operator: anyIn
                    valueSource: currentUser
                  - fieldUuid: stage
                    operator: anyIn
                    value:
                    - In Progress
                  - fieldUuid: updatedAt
                    operator: lastCustomDays
                    value: 1
      responses:
        '200':
          description: Paginated list of cards.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Card'
                  count:
                    type: integer
                    description: Total number of matching cards.
                  page:
                    type: integer
                  pageSize:
                    type: integer
        '400':
          description: Invalid rules, query parameters, or missing user context.
        '401':
          description: Invalid or missing API key.
        '403':
          description: Read access denied, API disabled, company mismatch, or invalid user selection.
        '404':
          description: Board or accessible active segment not found.
  /api/board/{boardId}:
    get:
      summary: List cards (deprecated)
      description: 'Deprecated: use POST /api/board/{boardId}/list. Both endpoints use the same read-only listing implementation and response. GET remains supported.


        Returns a paginated list of cards on the board.


        Field values are keyed by field UUID — use the schema endpoint to map keys to labels.

        Money fields are returned as `{ amount, currency }` where `amount` is a decimal.


        All filter params are optional and ANDed together.


        Supply segmentId OR rules (a JSON-encoded array), never both. Rules use the existing saved-segment format. Invalid rules fail with 400; missing, private-to-another-user, archived, or wrong-board segments return 404.


        Auth: API key, delegate token (boards:* or boards:{boardId} read scope), or partner bearer token with board-admin. Mobile tokens are not accepted. Keys/delegates require API-enabled boards; partner access retains its existing API-enabled bypass. API keys/partners may supply userId for an active company member; delegates can only use their token user. Without userId only public segments are visible. Public means company-shared.'
      operationId: listCards
      tags:
      - Cards
      security:
      - ApiKeyHeader: []
      - DelegateToken: []
      - PartnerBearer: []
      parameters:
      - name: boardId
        in: path
        required: true
        schema:
          type: string
        description: The board's UUID.
      - name: page
        in: query
        required: true
        schema:
          type: integer
          minimum: 0
          maximum: 9999
        description: Zero-based page number. Legacy GET parses the base-10 integer prefix (1.5 or 1e2 becomes 1).
      - name: pageSize
        in: query
        schema:
          type: integer
          minimum: 1
          maximum: 1000
          default: 20
        description: Number of cards per page. Legacy GET parses the base-10 integer prefix; omitted or empty defaults to 20.
      - name: updatedAtMin
        in: query
        schema:
          type: string
          format: date-time
        description: Only return cards updated after this ISO timestamp.
      - name: includeArchived
        in: query
        schema:
          type: boolean
          default: false
        description: Include archived cards. Legacy GET treats empty or the exact string false as false; any other nonempty string (including 1 or 0) as true. Omitted lets archive rules control selection.
      - name: relatedId
        in: query
        schema:
          type: string
        description: Only return cards where `references.value` contains this ID.
      - name: contactEmail
        in: query
        schema:
          type: string
        description: Resolves the email to contact IDs, then filters cards referencing those contacts.
      - name: keyTerm
        in: query
        schema:
          type: string
        description: Full-text autocomplete search on card title using the Atlas Search index.
      - name: assignee
        in: query
        schema:
          type: string
        description: Filter cards by assignee user ID.
      - name: segmentId
        schema:
          type: string
          maxLength: 256
        description: Existing accessible, active segment on this board; mutually exclusive with rules.
        in: query
      - name: rules
        schema:
          type: string
          maxLength: 64000
        description: JSON-encoded BoardFilterRule array, at most 100 rules. Prefer POST /list with a native JSON array.
        in: query
      - name: userId
        schema:
          type: string
          maxLength: 256
        description: Active company member whose private segments/currentUser values to use. API keys/partners may select a member; delegates cannot select another user.
        in: query
      responses:
        '200':
          description: Paginated list of cards.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Card'
                  count:
                    type: integer
                    description: Total number of matching cards.
                  page:
                    type: integer
                  pageSize:
                    type: integer
        '400':
          description: Invalid rules, query parameters, or missing user context.
        '401':
          description: Invalid or missing API key.
        '403':
          description: Read access denied, API disabled, company mismatch, or invalid user selection.
        '404':
          description: Board or accessible active segment not found.
      deprecated: true
    post:
      summary: Create or update a card
      description: 'Creates a new card on the board. Use field UUIDs (from the schema endpoint) as keys in the request body.


        To update an existing card, include its `_id` in the request body. The card must belong to this board.

        Fields not provided in the body are left unchanged on update.


        Contact fields take person ids from the Contacts API: a `person` field takes

        `{ "_id": "" }` (or `null` to clear it), and a `persons` field takes an

        array of them (`[]` clears it). Each id must be an existing contact in the board''s

        company. The stored value is expanded to `{ _id, name, duogram }`, where `name` is

        the contact''s full name and `duogram` its initials; any other keys sent are ignored.


        Card-link fields (`location`, `unit`, `relatedAptlets`) always take an array of

        `{ "_id": "" }` (`[]` clears the field). Each id must be a live

        (non-archived) card in the board''s company that matches every part of the

        field''s `filter` that is set: the card must be on one of the boards in

        `filter.aptletUuids`, and its board''s type must be in `filter.aptletTypes`.

        `location` and `unit` fields with no `aptletUuids` take cards from the built-in

        `location` and `unit` boards. Values are stored as `{ _id, name, duogram }`.'
      operationId: createCard
      tags:
      - Cards
      security:
      - ApiKeyHeader: []
      - DelegateToken: []
      parameters:
      - name: boardId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                _id:
                  type: string
                  description: Existing card ID. When provided, updates that card instead of creating a new one.
                name:
                  type: string
                  description: Card title (also accepted as `title`).
              additionalProperties:
                description: Any board field UUID as key, with the field's value.
            example:
              name: John Smith
              abc123: john@example.com
              ghi789: 1500
              jkl012:
                _id: aBcD1234eFgH5678i
              mno345:
              - _id: kLmN9012oPqR3456s
      responses:
        '200':
          description: Card created.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      _id:
                        type: string
                        description: ID of the created card.
        '400':
          description: A `person`/`persons` or `location`/`unit`/`relatedAptlets` value has the wrong shape, or names a contact or card that does not exist in the board's company or that the field's filter does not allow.
        '401':
          description: Invalid or missing API key.
        '403':
          description: API access is disabled for this board.
        '404':
          description: Board not found.
  /api/board/{boardId}/{cardId}:
    get:
      summary: Get a card
      description: Returns a single card by its ID.
      operationId: getCard
      tags:
      - Cards
      security:
      - ApiKeyHeader: []
      - DelegateToken: []
      parameters:
      - name: boardId
        in: path
        required: true
        schema:
          type: string
      - name: cardId
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Card data.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Card'
        '401':
          description: Invalid or missing API key.
        '403':
          description: API access is disabled for this board.
        '404':
          description: Card not found.
    delete:
      summary: Archive a card
      description: 'Archives the card. This is a soft delete — the card is never removed, only marked

        archived (same as the "Delete" action in the Aptly UI, which archives rather than

        hard-deletes).'
      operationId: deleteCard
      tags:
      - Cards
      security:
      - ApiKeyHeader: []
      - DelegateToken: []
      parameters:
      - name: boardId
        in: path
        required: true
        schema:
          type: string
      - name: cardId
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Card archived.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      _id:
                        type: string
                      archived:
                        type: boolean
        '401':
          description: Invalid or missing API key.
        '403':
          description: API access is disabled for this board.
        '404':
          description: Card not found.
  /api/board/{boardId}/{cardId}/comments:
    get:
      summary: List comments on a card
      description: Returns all comments on the specified card in chronological order.
      operationId: listComments
      tags:
      - Cards
      security:
      - ApiKeyHeader: []
      - DelegateToken: []
      parameters:
      - name: boardId
        in: path
        required: true
        schema:
          type: string
      - name: cardId
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Array of comments.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Comment'
              example:
                data:
                - id: lk3jf8
                  userId: user_abc
                  content: Application approved.
                  createdAt: '2026-01-15T10:30:00Z'
        '401':
          description: Invalid or missing API key.
        '403':
          description: API access is disabled for this board.
        '404':
          description: Board or card not found.
  /api/board/{boardId}/{cardId}/contacts:
    get:
      summary: List contacts linked to a card
      description: 'Returns all person contacts linked to the card via its person/persons fields.

        Returns an empty array if the board has no person fields or none are populated.'
      operationId: listCardContacts
      tags:
      - Cards
      security:
      - ApiKeyHeader: []
      - DelegateToken: []
      parameters:
      - name: boardId
        in: path
        required: true
        schema:
          type: string
      - name: cardId
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Array of linked contacts.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Contact'
        '401':
          description: Invalid or missing API key.
        '403':
          description: API access is disabled for this board.
        '404':
          description: Board or card not found.
  /api/board/{boardId}/{cardId}/comment:
    post:
      summary: Add or update a comment
      description: 'Adds a new comment to a card. To update an existing comment, include its `id` in the body —

        the `userId` must match the original comment''s author.'
      operationId: postComment
      tags:
      - Cards
      security:
      - ApiKeyHeader: []
      - DelegateToken: []
      parameters:
      - name: boardId
        in: path
        required: true
        schema:
          type: string
      - name: cardId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - userId
              - content
              properties:
                userId:
                  type: string
                  description: Aptly user ID of the comment author.
                content:
                  type: string
                  description: Comment text.
                id:
                  type: string
                  description: Existing comment ID — include to update rather than create.
      responses:
        '200':
          description: Comment created or updated.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Comment'
        '401':
          description: Invalid or missing API key.
        '404':
          description: Card or comment not found.
  /api/board/{boardId}/{cardId}/file:
    post:
      summary: Upload a file to a card
      description: 'Uploads a file and attaches it to a card. Send as `multipart/form-data` with the file in the `file` field.


        **Max file size:** 50 MB


        **Accepted types:** JPEG, PNG, GIF, WebP, SVG, PDF, Word, Excel, plain text, CSV, MP4, MOV, MP3, WAV'
      operationId: uploadFile
      tags:
      - Cards
      security:
      - ApiKeyHeader: []
      - DelegateToken: []
      parameters:
      - name: boardId
        in: path
        required: true
        schema:
          type: string
      - name: cardId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
              - file
              properties:
                file:
                  type: string
                  format: binary
      responses:
        '200':
          description: File uploaded and attached.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      fileId:
                        type: string
                      name:
                        type: string
                      size:
                        type: integer
                      type:
                        type: string
        '400':
          description: Missing file or unsupported file type.
        '401':
          description: Invalid or missing API key.
        '404':
          description: Card not found.
components:
  schemas:
    Card:
      type: object
      properties:
        cardId:
          type: string
          description: Unique ID of the card.
        boardUuid:
          type: string
          description: UUID of the board this card belongs to.
        archived:
          type: boolean
        assignee:
          type: string
          description: Full name of the assigned user.
        lastActivity:
          type:
          - object
          - 'null'
          description: Most recent conversation activity on the card (email, SMS or call), or null if the card has none.
          properties:
            content:
              type:
              - string
              - 'null'
              description: Body/text preview of the most recent message.
            type:
              type:
              - string
              - 'null'
              description: Activity type, e.g. `email`, `sms`, `voice`.
            direction:
              type:
              - string
              - 'null'
              enum:
              - in
              - out
              description: Direction of the message — `in` (inbound) or `out` (outbound).
            publishedAt:
              type:
              - string
              - 'null'
              format: date-time
            conversationUrl:
              type:
              - string
              - 'null'
              description: Deep link to the conversation thread in Aptly. Null when the activity is not attached to a thread.
      additionalProperties:
        description: Additional properties are dynamic board fields keyed by their field UUID. Fields of type `files` come back as an array of file objects and type `file` as a single file object — `{ fileId, name, size, type, url, expiresAt }`, where `url` is a presigned download link valid until `expiresAt` (1 hour, or sooner if the signing session ends first). An id with no readable file record degrades to `{ fileId }` with no `url`.
    BoardFilterRule:
      type: object
      properties:
        fieldUuid:
          type: string
          description: 'Field uuid from the board catalog (HIRO: get_board_fields.fields); system fields include assignee, stage, updatedAt.'
        key:
          type: string
          description: Exact filter key from the field's filters array. Required to select a subfield when one uuid has multiple filters.
        operator:
          type: string
          description: Supported operator from the filter's operatorSet in the catalog's operatorSets dictionary. Greater-than is spelled gratherThan for saved-rule compatibility.
        value:
          description: 'between takes [minimum, maximum], e.g. ["2026-09-28", "2026-10-04"] for ISO dates or [0, 100] for numbers. Money values are {amount: cents, currency?: string}; money ranges use two such objects. anyIn/notIn require nonempty arrays of option values, user ids, booleans/null, or contact {_id} objects as appropriate for the field. Use option.value when present, otherwise the literal option string/label. Contact equal uses {_id}. Date comparisons use ISO dates; specificPeriod uses {period: dayOfYear|month|quarter|year|week, adjustment?: integer}. For feeAmount fields, wrap any supplied value in {end: value}, including {end: [minimum, maximum]} for between. Omit value for noValue operators.'
        valueSource:
          type: string
          enum:
          - currentUser
          description: For user anyIn/notIn rules, resolves the authenticated/selected user on the server. Omit value.
        valueFieldUuid:
          type: string
          description: Optional comparison field uuid or catalog key; equal, notEqual, lessThan, gratherThan only. Omit value.
        defaultValueField:
          type: string
          description: Optional catalog field/key used if the filtered field is missing.
      required:
      - fieldUuid
      - operator
    Comment:
      type: object
      properties:
        id:
          type: string
        userId:
          type: string
        content:
          type: string
        createdAt:
          type: string
          format: date-time
    BoardCardListRequest:
      type: object
      required:
      - page
      properties:
        page:
          type: integer
          minimum: 0
          maximum: 9999
          description: Zero-based page number.
        pageSize:
          type: integer
          minimum: 1
          maximum: 1000
          default: 20
          description: Number of cards per page.
        updatedAtMin:
          type: string
          format: date-time
          description: Only return cards updated after this ISO timestamp.
        includeArchived:
          type: boolean
          default: false
          description: Include archived cards. If omitted, an explicit archived rule controls archive selection; otherwise active cards only. An explicit false intersects with the rules.
        relatedId:
          type: string
          description: Only return cards where `references.value` contains this ID.
        contactEmail:
          type: string
          description: Resolves the email to contact IDs, then filters cards referencing those contacts.
        keyTerm:
          type: string
          description: Full-text autocomplete search on card title using the Atlas Search index.
        assignee:
          type: string
          description: Filter cards by assignee user ID.
        segmentId:
          type: string
          maxLength: 256
          description: Existing accessible, active segment on this board; mutually exclusive with rules.
        rules:
          type: array
          maxItems: 100
          items:
            $ref: '#/components/schemas/BoardFilterRule'
          description: Ad hoc saved-segment rules, ANDed together. Requires an explicit board. Supply rules OR segmentId. Invalid rules are rejected.
        userId:
          type: string
          maxLength: 256
          description: Active company member whose private segments/currentUser values to use. API keys/partners may select a member; delegates cannot select another user.
      description: Read-only card listing. Supply segmentId OR rules; existing simple filters intersect with either. Segment/rule queries exclude deleted cards unless explicitly selected by a rule. No filter or card is saved. Saved segments must contain a rules array; missing or malformed rules require re-saving. An explicitly empty rules array matches all cards within the remaining filters.
    Contact:
      type: object
      properties:
        _id:
          type: string
          description: MongoDB ObjectId of the contact.
        uuid:
          type: string
        firstname:
          type: string
        lastname:
          type: string
        fullName:
          type: string
          description: Computed display name (first + last, or company name for org records).
        duogram:
          type: string
          description: Two-letter initials derived from first and last name.
        photoId:
          type:
          - string
          - 'null'
        imageUrl:
          type:
          - string
          - 'null'
          description: CDN thumbnail URL for the contact's photo, or null if none.
        email:
          type: string
        phone:
          type: string
        typeId:
          type: string
        companyId:
          type: string
        address:
          type: object
        title:
          type: string
        alerts:
          type: array
          items:
            type: object
        company:
          type: string
          description: Company name — populated when isCompany is true.
        isCompany:
          type: boolean
  securitySchemes:
    ApiKeyHeader:
      type: apiKey
      in: header
      name: x-token
    DelegateToken:
      type: apiKey
      in: header
      name: Authorization
      description: 'Delegate token issued by the platform. Format: `DelegateToken <token>`'
    PartnerBearer:
      type: http
      scheme: bearer
      description: 'Partner token. Format: `Authorization: Bearer <token>`'
x-provenance:
  method: harvested
  publisher: Aptly
  source: https://docs.getaptly.com/openapi.yaml
  note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json);
    stamped by stamp-openapi-provenance.py (roadmap#793)