Aptly Templates API
The Templates API from Aptly — 2 operation(s) for templates.
The Templates API from Aptly — 2 operation(s) for templates.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
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.curl "https://apis.io/api/v1/apis/aptly:aptly-templates-api"
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.
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: 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)