Aptly Templates API

The Templates API from Aptly — 2 operation(s) for templates.

Operations 4

GET /api/templates List templates #
POST /api/templates Create a template #
GET /api/templates/{id} Get a template #
PUT /api/templates/{id} Update a template #

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-templates-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-templates-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Aptly Templates 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: Templates
paths:
  /api/templates:
    get:
      summary: List templates
      description: 'Returns communication templates for the company. All filter parameters are optional.


        Accepts an API key (`x-token`), delegate token (`Authorization: DelegateToken `),

        or partner token (`Authorization: Bearer ` with `templates` permission).

        When using a partner token, pass `companyId` as a query parameter.'
      operationId: listTemplates
      tags:
      - Templates
      security:
      - ApiKeyHeader: []
      - DelegateToken: []
      - PartnerBearer: []
      parameters:
      - name: companyId
        in: query
        schema:
          type: string
        description: Company ID. Required when using a partner token; resolved automatically for API key and delegate token auth.
      - name: templateType
        in: query
        schema:
          type: string
          enum:
          - sms
          - email
          - form
          - eSignature
          - pdf
          - blockDocument
        description: Filter by template type.
      - name: aptletUuid
        in: query
        schema:
          type: string
        description: Filter by associated board UUID.
      - name: archived
        in: query
        schema:
          type: boolean
        description: Filter by archived status.
      responses:
        '200':
          description: Array of templates.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Template'
        '400':
          description: Missing companyId.
        '401':
          description: Invalid or missing credential.
    post:
      summary: Create a template
      description: 'Creates a communication template.


        The acting user — the delegate token''s own user, or the body `userId` when

        authenticating with an API key or partner token — must belong to the company and

        hold the `setup` or `setup_communication_templates` permission.


        Only plain templates can be created here — `htmlBuilder` must be `false` or

        omitted.


        `attachmentIds` are resolved against the company''s uploaded files, stored on the

        template as full attachment entries, and tied to it so the detached-upload cleanup

        leaves them alone — ids that no longer resolve are dropped. A `pdf` template''s

        `subject` becomes a file name, so characters that are illegal in one are stripped.


        ### Merge fields


        `subject` and `content` may contain merge placeholders, which are replaced with

        the recipient''s, board card''s or company''s own values when the template is sent.


        Fetch the available fields from

        `GET /api/board/{boardId}/merge-fields` for the board the template is used with.

        Every item in that response is `{ label, value }` — `label` is what to show a

        human, `value` is what goes inside the braces:


        ```

        {{firstname}}

        {{Locations["Rent"]}}

        {{customFields.7Lq2.LoyaltyTier}}

        ```


        A placeholder may carry a fallback, used when the field is empty or unknown:


        ```

        {{firstname || fallback: there}} -> "there" when the contact has no first name

        {{Locations["Rent"] || fallback: TBD}} -> "TBD" when the card has no rent

        {{firstname || fallback: }} -> renders nothing at all

        ```


        Everything after `fallback:` up to the closing braces is the fallback text, and an

        empty one (or `_blank`) renders nothing.


        Placeholders are **shape**-checked on write — an unclosed `{{`, an empty field

        name, or a malformed bracket reference such as `Locations["Rent]` is rejected with

        400. Whether the field exists is not checked: an unknown field is normal (boards

        differ), and simply renders as its fallback at merge time.'
      operationId: createTemplate
      tags:
      - Templates
      security:
      - ApiKeyHeader: []
      - DelegateToken: []
      - PartnerBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TemplateUpsert'
            examples:
              email:
                summary: Plain email template
                value:
                  companyId: '{{companyId}}'
                  userId: '{{userId}}'
                  name: Move-in welcome
                  description: Sent to new residents on move-in day
                  templateType: email
                  subject: Welcome to your new home
                  content: <p>Welcome!</p>
                  htmlBuilder: false
      responses:
        '201':
          description: Template created.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Template'
        '400':
          description: Missing companyId, or an invalid payload.
        '401':
          description: Invalid or missing credential.
        '403':
          description: The acting user lacks the template permission.
  /api/templates/{id}:
    get:
      summary: Get a template
      description: Returns a single template by its ID. The template must belong to the authenticated company.
      operationId: getTemplate
      tags:
      - Templates
      security:
      - ApiKeyHeader: []
      - DelegateToken: []
      - PartnerBearer: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
        description: Template ID.
      - name: companyId
        in: query
        schema:
          type: string
        description: Required for partner token auth.
      responses:
        '200':
          description: Template record.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Template'
        '401':
          description: Invalid or missing credential.
        '404':
          description: Template not found.
    put:
      summary: Update a template
      description: 'Replaces the fields of an existing template. The payload and its validation are

        identical to `POST /api/templates` — including the merge-field placeholders

        documented there, whose available `value`s come from

        `GET /api/board/{boardId}/merge-fields`. On top of the template permission, the

        acting user must have access to the library folder the template sits in. A

        template that does not exist — or belongs to another company — returns 404; an

        archived one returns 403, since it is the caller''s own and

        `GET /api/templates/{id}` still returns it.'
      operationId: editTemplate
      tags:
      - Templates
      security:
      - ApiKeyHeader: []
      - DelegateToken: []
      - PartnerBearer: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
        description: Template ID.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TemplateUpsert'
            examples:
              email:
                summary: Plain email template
                value:
                  companyId: '{{companyId}}'
                  userId: '{{userId}}'
                  name: Move-in welcome
                  description: Sent to new residents on move-in day
                  templateType: email
                  subject: Welcome to your new home
                  content: <p>Welcome!</p>
                  htmlBuilder: false
      responses:
        '200':
          description: Template updated.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Template'
        '400':
          description: Missing companyId, or an invalid payload.
        '401':
          description: Invalid or missing credential.
        '403':
          description: The acting user lacks the template permission or folder access.
        '404':
          description: Template not found.
components:
  schemas:
    TemplateUpsert:
      type: object
      required:
      - name
      - description
      - templateType
      - subject
      - content
      properties:
        companyId:
          type: string
          description: Required with a partner token; resolved from an API key or delegate token.
        userId:
          type: string
          description: The acting user. Required with an API key or partner token; a delegate token supplies its own.
        name:
          type: string
        description:
          type: string
        templateType:
          type: string
          enum:
          - sms
          - email
          - form
          - eSignature
          - pdf
          description: Template kind. `blockDocument` is not accepted — it is an internal type for document blocks, not a user-facing template.
        subject:
          type: string
          description: Email subject, or the file name for a `pdf` template — in which case filename-illegal characters are stripped. Merge placeholders work here too, and are shape-checked the same way.
        content:
          type: string
          description: 'Template body. Merge placeholders take the form `{{value}}` or `{{value || fallback: text}}`, where `value` is an item''s `value` from `GET /api/board/{boardId}/merge-fields` — for example `{{firstname}}`, `{{Locations["Rent"] || fallback: TBD}}`. They are checked for shape — an unclosed `{{`, an empty field name or a malformed bracket reference is rejected. Whether each field exists is not checked: an unknown one renders as its fallback at merge time.'
        htmlBuilder:
          type: boolean
          enum:
          - false
          default: false
          description: Must be `false` or omitted. HTML-builder templates keep their markup in a builder-owned `builderData` format and can only be authored in the app.
        builderData:
          type: object
          description: Builder document, when one already exists.
        folderId:
          type: string
          description: Library folder the template belongs to — must be an existing, non-archived folder in the company. Governs who may edit the template.
        aptletUuid:
          type: string
          description: Board the template is scoped to. Must be an existing, non-archived board in the company.
        signature:
          type: string
        attachmentIds:
          type: array
          items:
            type: string
          description: Uploaded file ids to attach.
    Template:
      type: object
      properties:
        _id:
          type: string
          description: Template ID.
        companyId:
          type: string
          description: Company the template belongs to.
        name:
          type: string
          description: Template display name.
        templateType:
          type: string
          enum:
          - sms
          - email
          - form
          - eSignature
          - pdf
          - blockDocument
          description: Template category.
        archived:
          type: boolean
        createdAt:
          type: string
          format: date-time
        createdBy:
          type: string
          description: User ID of the creator.
        updatedAt:
          type: string
          format: date-time
      additionalProperties:
        description: Additional properties depend on the templateType (e.g. `subject`, `content` for email templates).
  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)