Start Here

Quickstart: first API call

Create a service account, assign its roles, mint an API key that runs as that account, and retrieve records from one Object.

This quickstart makes one POST /jql request with an API key. Use it when a backend service, integration worker, or private automation needs to read Antly data, such as records from one Object.

The key does not have its own permission list. It runs as a service account, and it can do whatever that account's roles allow.

1. Create a service account

In Antly, open Settings → Identity & access → Service accounts and create an account. Open it and assign roles on the Roles tab.

A role is a set of namespace:action rules, the same rules you grant to a person. To read one Object, include that Object's namespace. If the Object namespace is objects.NationalAssetRegister, the role needs objects.NationalAssetRegister:retrieve. Add retrieveOne, create, update, or delete only for the actions the integration should perform.

The service account must stay active. An API app cannot run as a person, a customer, or an AI agent.

2. Create an API application

Open Settings → Application → API and create an application. Choose the service account from the previous step. Antly shows the key once. Store it as a secret in your integration environment. Do not ship it in browser code.

The key looks like jql:kp-<workspace-alias>::<secret> (kp is persistent, ke is ephemeral). See /developer/api-applications-keys for rotation, expiry, and the request headers.

3. Send a retrieve request

Send requests to the tenant's API origin. Prefer the Authorization header. X-Antly-Api-Key also works.

Export the token first (export ANTLY_JQL_TOKEN='jql:kp-…::…'). Do not paste a raw key into a double-quoted -H. zsh will expand $ inside it and Antly will return API_KEY_INVALID.

Use the Object's own namespace. Replace objects.NationalAssetRegister and the field aliases with the Object you are reading.

bash
1curl -X POST "https://<tenant-domain>/jql" \ 2 -H "Authorization: Bearer $ANTLY_JQL_TOKEN" \ 3 -H "Content-Type: application/json" \ 4 -d '{ 5 "__meta__": { 6 "schema": "model", 7 "namespace": "objects.NationalAssetRegister", 8 "intent": "retrieve", 9 "return": { 10 "id": null, 11 "reference": null 12 } 13 } 14 }'

Add each field you need under return, using the Object's field aliases. The rows come back under data. Message, status, pagination, and debugging details sit beside it. See /reference/jql-overview and /reference/errors.

PostgreSQL Objects use schema: "model". DynamoDB Objects use schema: "nosql" and the same namespace, with cursor pagination. The engine is fixed when the Object is created.

If the call returns 403 PERMISSION_DENIED, the service account's roles do not include that namespace and action. If it returns 403 API_KEY_NAMESPACE_NOT_EXPOSED, the namespace is outside the API key ceiling (profiles.*, objects.*, tickets.*, tasks.*, workflow.*), even when the role would allow it for a signed-in person.

4. Create a record

Use create when the service account's roles include create on that Object:

json
1{ 2 "__meta__": { 3 "schema": "model", 4 "namespace": "objects.NationalAssetRegister", 5 "intent": "create", 6 "authenticationClass": "api_key", 7 "return": { 8 "id": null, 9 "reference": null 10 } 11 }, 12 "assetName": "Example asset" 13}

Field names are the Object's aliases. You do not send a separate object id when the namespace is the Object itself.

For public browser submissions, do not use api_key. Published public object forms use the public object controllers and the public authentication class. See /developer/public-access and /developer/embed-public-forms.