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.
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:
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.