REST API · v1 · Beta
One API,
every object.
Ahoy's built-in types and the ones your org defines, read and written through the same request shape. 20 operations, no endpoint sprawl.
Create a key in Settings → API & Service Accounts in
the Ahoy app, then send it as
Authorization: Bearer.
v1 is in beta — breaking changes are
announced before they ship.
/rest/v1/objects/ahoy_contact/records/ curl https://api.ahoy.ai/rest/v1/objects/ahoy_contact/records/ \ -H "Authorization: Bearer $AHOY_API_KEY"
application/json {
"data": [
{
"id": "rec_01J8Z2K9QW3X4Y5Z6A7B8C9D",
"properties": {
"ahoy_first_name": "Ada",
"ahoy_last_name": "Lovelace",
"ahoy_email": ["ada@example.com"]
}
}
],
"pagination": { "next_cursor": "eyJvIjoyNX0", "has_more": true }
} Three steps to your first call
-
Create a key
In the Ahoy app, open Settings → API & Service Accounts and choose which object types the key may read and write. It is shown once.
-
Check it works
GET /rest/v1/self/echoes the org and principal the key resolves to. If this returns 200, everything else will authenticate. -
See what you can reach
GET /rest/v1/objects/lists exactly the types this key can see, each with the writes it allows. Read this rather than hard-coding type names — the schema is per-org.
Start here
Authentication→
Bearer tokens scoped to one org, reaching exactly as far as the person who minted them.
Objects and properties→
The schema is per-org. Discover object types and properties instead of hard-coding them.
Filtering→
A typed $and / $or tree, validated against each property's field type.
Pagination→
Cursor-based on every list endpoint. Follow next_cursor until has_more is false.
Writing records→
Create, update, upsert and associate — plus the idempotency rules that make retries safe.
Batch operations→
Up to 50 records per request, with a per-item result for each one.
Rate limits→
Per org, with remaining quota on every response header.
Errors→
RFC 9457 problems with a closed code enum. Every error links to its own page.
Every endpoint
Your credential
1
Field types
1
Object types
3
Records
15
- GET
/objects/{object_type}/records/List records - POST
/objects/{object_type}/records/Create a record - PUT
/objects/{object_type}/records/Create or update a record by a matching property - POST
/objects/{object_type}/records/aggregate/Aggregate records - POST
/objects/{object_type}/records/batch/create/Create up to 50 records - POST
/objects/{object_type}/records/batch/delete/Delete up to 50 records - POST
/objects/{object_type}/records/batch/update/Update up to 50 records - POST
/objects/{object_type}/records/batch/upsert/Create or update up to 50 records by a matching property - POST
/objects/{object_type}/records/query/Query records with a filter tree - DELETE
/objects/{object_type}/records/{id}/Delete a record - GET
/objects/{object_type}/records/{id}/Get a record - PATCH
/objects/{object_type}/records/{id}/Update a record - GET
/objects/{object_type}/records/{id}/associations/List a record's associations - DELETE
/objects/{object_type}/records/{id}/associations/{association_type}/{target_id}/Remove an association between two records - PUT
/objects/{object_type}/records/{id}/associations/{association_type}/{target_id}/Associate two records