Skip to main content
Deprecated board listing: GET /api/board/{boardId} examples on this page remain supported, but new integrations should use the read-only POST /api/board/{boardId}/list with the same parameters in a JSON body. Card create/update POST is unchanged. See Board segments.
The Aptly SDK is loaded via a single script tag and populates window.aptly. New to building embedded apps? Start with the embedded apps guide. Related documentation:

Canonical pattern

Always call requestToken with { version: 2 }. It returns a result object — token on success, structured error on failure — so you can handle rate limits and other failures without a separate side channel.
Note: requestToken() called without arguments returns a bare string | null for backward compatibility. Prefer { version: 2 } in all new code.

API reference

Supply subject and the complete content when preparing an email draft. Text displayed outside the composer is not copied into it. Hiro replaces its blank contact lookup email button with an explicitly requested draft, including after resume.

Fetching board data

aptly.fetch prepends the Aptly API base URL and handles auth automatically. Pass the path starting from /board/ — omit /api.

Pagination

Pages are zero-based. The first page is page=0, the second is page=1, and so on. The page parameter is required — omitting it returns a 400 error.
To page through all records:

Query parameters

Schema endpoint

To get the field definitions for a board (key → label → type mapping):
The schema endpoint requires no additional parameters and returns an array directly (not wrapped in { data }).

Managing tasks

aptly.fetch passes any method through, so tasks can be read and changed directly from an embed. Reads need the tasks:* read scope, writes the tasks:* write scope; the token supplies the acting user.
Complete a task with checked: true; close or skip it with archived: true. bulk-update takes taskIds (up to 100) or aptletInstanceId (open tasks only unless includeCompleted: true) and reports per-task failures in failed instead of stopping. See the Tasks section of the API reference for every field.

Config scoping

aptly.config always contains the fully merged configuration for the current context — app devs just read aptly.config.YOUR_KEY without knowing which scope a value came from. Admins set a contextScope on each app that controls how config values are stored: Merge priority: user > board > company. If the same key is set at multiple levels, the narrowest scope wins.
Configuring board-scoped apps: Users configure board-scoped apps directly in the board view settings panel, where the board context is known. Company and user-scoped apps are configured in the app store.

Rate limiting

Token requests are rate-limited per browser connection (not per user account), so opening the same app in multiple tabs does not share a quota. The default limit is 60 token requests per 60 seconds per connection. When the limit is exceeded, requestToken({ version: 2 }) returns { token: null, error } where error is:

Handling rate limit errors

Use { version: 2 } and check the error field:
aptly.fetch does not automatically retry on rate limit errors — it only retries once on 401. Your app is responsible for scheduling retries when error.code === 'RATE_LIMITED'.

URL params (Option C dev testing)

Append any of these to your app’s URL to simulate Aptly context with no code changes: Example:
When running inside Aptly, URL params are ignored — the real postMessage context takes priority.

Standard boards

aptly.boards delivers pre-fetched schema and records for standard Aptly board types — no fetches required. The app admin selects which boards to pre-load in the marketplace admin panel. Only declared boards are populated; undeclared keys are null.

Board data shape

Each non-null entry is a BoardData object:

Usage

Board keys

A key is null if the app didn’t declare that board, or if the company doesn’t have it. Always guard:

Fetching more records

The first 50 records are pre-loaded. If total > 50, use aptly.fetch to page through the rest:

Dev mode

aptly.boards is null by default in startEmulation and APTLY_DEV (no live Aptly session to deliver data). Pass a boards override to simulate it locally. You can use either the full rich object or a plain UUID string (the SDK normalizes it):
Or via startEmulation: