Aglyn REST API
The Aglyn REST API gives you programmatic access to your organization's data — datasets and records, contacts and the CRM around them — companies, pipelines, deals, tasks, activities, email templates and each site's leads — sites and their form submissions, your store's orders and products, and your media library. Use it to sync content from another system, push orders into accounting, record shipments from a 3PL or warehouse system, feed a catalog to a marketplace, sync a CRM's contacts and deals in either direction, log calls from a dialer, back up records, or build an integration.
The REST API is included on Business and every plan above it. Create keys from Organization → Settings → API keys.
Base URL
https://app.aglyn.com/api/v1
All requests are over HTTPS and every response is JSON. The version lives in the path; there's no version header.
Quick start
Check your key and see what it can do:
curl https://app.aglyn.com/api/v1/me \
-H "Authorization: Bearer aglyn_sk_your_key_here"
{
"object": "api_key",
"org": "org_abc123",
"scopes": ["datasets:read", "datasets:write"]
}
Then read some data — here, the first page of a dataset's records:
curl "https://app.aglyn.com/api/v1/datasets" \
-H "Authorization: Bearer aglyn_sk_your_key_here"
curl "https://app.aglyn.com/api/v1/datasets/ds_team/records?limit=100" \
-H "Authorization: Bearer aglyn_sk_your_key_here"
In JavaScript
const res = await fetch('https://app.aglyn.com/api/v1/datasets/ds_team/records', {
headers: { Authorization: `Bearer ${process.env.AGLYN_API_KEY}` },
})
if (!res.ok) {
const { error } = await res.json()
throw new Error(`${error.type}: ${error.message}`)
}
const { data, next_cursor, has_more } = await res.json()
Paging through everything
Lists are ordered by id and paged with an opaque cursor, so a full sync is a loop:
let cursor = null
const all = []
do {
const url = new URL('https://app.aglyn.com/api/v1/datasets/ds_team/records')
url.searchParams.set('limit', '100')
if (cursor) url.searchParams.set('cursor', cursor)
const page = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.AGLYN_API_KEY}` },
}).then((r) => r.json())
all.push(...page.data)
cursor = page.next_cursor
} while (cursor)
Read ordering before you assume page 1 holds the newest records — it doesn't.
Machine-readable description
The whole API is described as OpenAPI 3.1 at:
GET https://app.aglyn.com/api/v1/openapi.json
It needs no key. A description of how to authenticate that itself required authentication would be useless at the only moment you want it, and it contains nothing this documentation does not already publish.
Point a generator at it and you get a typed client — every resource, every filter, the pagination envelope and the error shape, without hand-writing types this API already knows:
npx @openapitools/openapi-generator-cli generate \
-i https://app.aglyn.com/api/v1/openapi.json -g typescript-fetch -o ./aglyn-client
Two things to know when reading it:
- The schemas use JSON Schema 2020-12, so a field that can be
nullis a type union ("type": ["string", "null"]), not OpenAPI 3.0'snullable: true. A generator that only understands 3.0 will get optionality wrong. - Most write bodies close — an unknown field is rejected, not ignored. The
exceptions read only the members they document and ignore the rest:
datasets and records, whose record
valuesalso drop any field id the dataset's model doesn't define; creating a site; and media uploads.
Service endpoints
Three endpoints need no scope; any valid key can call them.
GET /v1
What this API is and what it serves.
{
"object": "api",
"name": "Aglyn REST API",
"version": "v1",
"documentation": "https://docs.aglyn.com/api",
"resources": ["sites", "media", "contacts", "companies", "pipelines", "deals", "tasks", "activities", "leads", "email-templates", "datasets"]
}
This lists only top-level resources. Form submissions, orders
and products all live under a site
(/v1/sites/{siteId}/…) and are deliberately absent, so a client that walks this list
never builds a path that 404s. media is here because
/v1/media — the organization library — really is a top-level
path; each site's own files are additionally at /v1/sites/{siteId}/media. The five
CRM resources are organization-level like contacts, and so are top-level here. Leads are
a site's rows, but the path is /v1/leads with the site as a
parameter, so the path is what is listed.
GET /v1/me
Introspect the key you're calling with — useful for verifying a key after rotation, or for failing fast at startup with a clear message.
{
"object": "api_key",
"org": "org_abc123",
"scopes": ["datasets:read", "datasets:write"]
}
GET /v1/usage
Where you stand against every plan band this month — requests, contacts, datasets and dataset storage — and, for each, whether crossing it bills or refuses; plus the size of each CRM collection, for sizing a sync. See Usage.
{
"object": "usage",
"month": "2026-08",
"apiRequests": { "used": 18422, "included": 100000, "remaining": 81578, "metered": true }
}
Resources
| Resource | Description |
|---|---|
| Datasets & records | Create, read, update, and delete datasets and the records inside them — the one resource the API can provision from nothing. |
| Contacts | Read your organization's contacts, add the people your own systems own, and edit their name, tags, notes and CRM profile. |
| Companies | The accounts your contacts work for — keyed by domain, with an owner and an address. |
| Pipelines | The stages a deal moves through. Read-only; seeded by the first deal. |
| Deals | Opportunities with a value, a stage and a status — create them, move them, close them. |
| Tasks | Calls, emails, meetings and to-dos with a due date, against a contact, company or deal. |
| Activities | What happened — a write-once log of calls, meetings and notes. |
| Leads | A site's work queue — everyone it has captured, with status, owner and notes — and the conversion of a lead into a contact, a company and a deal. |
| Email templates | The letters a team sends from a record — templates and snippets, with merge fields. |
| Sites | List sites and read their details. |
| Form submissions | Read a site's form submissions, mark them read as you process them, and delete them after export. |
| Orders | Read a site's store orders — line items, totals, refunds, disputes — and record shipments against them. |
| Products | Read a site's catalog — variants, prices, stock levels. |
| Media | List files in the organization library and in each site's media. |
Orders and products need a plan that includes commerce, in addition to their
scope — see each page's plan note. Companies, pipelines, deals, tasks, activities,
leads and email templates need a plan that includes the CRM suite (Starter and
above); a plan without it answers plan_required with code: "crm" on all seven, while
contacts keep working.
For event-driven integrations, see Webhooks — push instead of poll.
Everything you need to know
- Authentication — API keys and scopes.
- Rate limits & usage — 120 requests/minute per key, and how the monthly quota bills.
- Conventions — pagination, ordering, errors, and idempotency.