API Reference
The Data Co APIv1Beta
The Data Co API syncs your organization's operational data into your own systems. It is a server-to-server API: sync each resource into your warehouse and query it there.
Base URL
https://api.thedataco.com/v1Authentication
Send your API key in the Authorization header:
Authorization: Bearer tdc_live_...Keys are scoped to one organization and one environment. Sandbox keys start with tdc_test_ and return demo data; live keys start with tdc_live_.
Keep keys in a secret manager or backend environment variable. Do not use them in browser, mobile, or desktop clients, and do not commit them to source control.
Quickstart
# check your key, scopes, and connections
curl https://api.thedataco.com/v1/access \
-H "Authorization: Bearer tdc_live_..."
# first page of revenue entries
curl "https://api.thedataco.com/v1/revenue-entries?limit=500" \
-H "Authorization: Bearer tdc_live_..."
# next page
curl "https://api.thedataco.com/v1/revenue-entries?limit=500&cursor=..." \
-H "Authorization: Bearer tdc_live_..."Response Format
List endpoints:
{
"data": [],
"pagination": {
"nextCursor": null,
"hasMore": false,
"limit": 500
}
}Single-record endpoints:
{
"data": {}
}Every response carries an X-Request-Id header. Include it when contacting support about a request.
Pagination
| Parameter | Description |
|---|---|
limit |
Records per page. Default 500, maximum 5000. |
cursor |
The pagination.nextCursor of the previous page. |
Records are ordered by updatedAt ascending, then id. Request the next page with nextCursor until hasMore is false.
Cursors are opaque and valid for at least 24 hours. A cursor is bound to the key, the resource, and the updatedSince of the request that issued it; limit may change between pages. An invalid, expired, or mismatched cursor returns 400 invalid_cursor: restart from your last updatedSince checkpoint.
Incremental Sync
Every list endpoint accepts updatedSince, an inclusive lower bound on updatedAt as an ISO 8601 UTC timestamp.
Initial sync: request each resource without updatedSince, page to the end, upsert by id and connectionId, and store the maximum updatedAt seen.
Ongoing sync: request each resource with updatedSince set to your stored checkpoint, page to the end, upsert, and store the new maximum updatedAt. Treat a record with a non-null deletedAt as deleted; keep the row so references still resolve.
updatedAt changes only when a record's values change, including when it is deleted. Because updatedSince is inclusive, a record can appear in two consecutive syncs; upserts make this safe. A reference to a record you have not synced yet resolves on the next sync.
Sync Status
GET /v1/sync-status returns, for each resource your key can read, when it last finished publishing.
{
"data": [
{ "resource": "appointments", "latestSyncAt": "2026-05-12T06:15:00Z" },
{ "resource": "revenue-entries", "latestSyncAt": "2026-05-12T05:58:12Z" },
{ "resource": "campaigns", "latestSyncAt": null }
]
}latestSyncAt is per resource and is null for a resource that has never published. Checkpoint incremental syncs on updatedAt, not on this value.
Identifiers
| Resource | id |
Notes |
|---|---|---|
banners, clinics |
integer | Organization-level. |
employees, patients, appointments, revenue-entries, payments, leads |
string | Opaque. Identified with connectionId. |
campaigns |
string | Opaque. One campaign on one day; campaignId groups a campaign across days. |
A connection is one source system connected to your organization: an EMR, a CRM, an advertising account. Every record on the seven connection-scoped resources carries the opaque connectionId of the connection it came from, and a record is identified by (id, connectionId). GET /v1/access lists your connections.
Store ids as strings of unbounded length. Do not parse them or sort on them.
Data Types
| Type | Format |
|---|---|
| Date | YYYY-MM-DD |
| Timestamp | ISO 8601 UTC, e.g. 2026-05-12T14:30:00Z |
| Clinic-local time | YYYY-MM-DDTHH:MM:SS with no zone, e.g. 2026-05-12T14:00:00, in the clinic's timezone. Used for appointment startTime, endTime, and createdAt. |
| Decimal and money | JSON string, e.g. "1250.00". Money is USD. |
| Integer | JSON number |
| Boolean | JSON boolean |
| Empty value | null |
Enumerated Values
Values are case-sensitive. The sets may grow.
gender (patients)
Male, Female, Not Specifiedstatus (appointments)
scheduled, confirmed, cancelled, rescheduled, no_show, completed, in_progress, unknownrole (employees)
Unassigned, Aesthetician, Aesthetician - All Devices, Consultant, Dermatologist,
Doctor, Hybrid Injector, Injector, Laser Technician, Nurse, Nurse Injector,
Support Staff, Surgeon, Therapist, WellnessparentCategory (appointments, revenue-entries)
Surgical Procedures, Products, Injectables, Energy and Device Treatments,
Body Contouring (Non-Surgical), Clinical Aesthetics, Wellness and Hormones,
Hair Restoration, Consults & Follow Ups, Medical and General, Admin, FeessubCategory and serviceCategory (appointments, revenue-entries)
parentCategory |
subCategory |
serviceCategory values |
|---|---|---|
| Surgical Procedures | Face | Facelift, Neck Lift, Lip Lift, Cheek Augmentation, Cheek Reduction, Buccal Fat Removal, Blepharoplasty, Rhinoplasty, Brow Lift, Otoplasty, Chin Augmentation, Scar Revision, Earlobe Repair, Fat Grafting, Other |
| Surgical Procedures | Breast | Breast Augmentation, Breast Lift (Mastopexy), Breast Reduction, Implant Removal/Exchange, Scar Revision, Fat Grafting, Nipple Repair, Other |
| Surgical Procedures | Body | Arm Lift, Butt Lift, Liposuction, Mommy Makeover, Thigh Lift, Tummy Tuck, Labiaplasty, Scar Revision, Fat Grafting, Other |
| Surgical Procedures | Hair | FUE, FUT, Neograft, Artas, Other |
| Surgical Procedures | Reconstructive | Breast Reconstruction, Skin Cancer Reconstruction, Trauma Repair, Other |
| Surgical Procedures | Gender-Affirming | Top Surgery, Facial Feminization, Facial Masculinization, Body Contouring (Gender-Affirming), Tracheal Shave, Other |
| Surgical Procedures | Other | Scar Revision, Other |
| Surgical Procedures | Adjustments | Adjustments |
| Products | Surgical Implants | Breast Implants, Allografts, Other |
| Products | Surgical Garments | Compression Garments, Surgical Bras, Abdominal Binders, Other |
| Products | Other Surgical Supplies | Puregraft, Other |
| Products | Skincare | Sunscreen, Cleanser, Moisturizer, Serum, Eye Cream, Mask, Other |
| Products | Prescription | Latisse, Upneeq, Hydroquinone, Other |
| Products | Other | Supplements, Other |
| Injectables | Neurotoxins | Botox, Dysport, Xeomin, Jeuveau, Daxxify, Other |
| Injectables | Fillers | Juvederm, Restylane, RHA, Revanesse, Belotero, Evolysse, PhalloFILL, Other |
| Injectables | Biostimulators | Sculptra, Radiesse, Bellafill, Renuva, alloClae, ariessence, Other |
| Injectables | Regenerative | PRP, PRF, Exosomes, EZGEL, Other |
| Injectables | Threads | PDO Threads, InstaLift, Other |
| Injectables | Dissolvers | Hyaluronidase, Other |
| Injectables | Skin Quality | Skinvive, Skinboosters, Mesotherapy, Other |
| Injectables | Vein Therapy | Sclerotherapy, Asclera, Other |
| Injectables | Other | Other |
| Energy and Device Treatments | Laser Hair Removal | Laser Hair Removal, Electrolysis, Other |
| Energy and Device Treatments | Laser Resurfacing (Ablative) | CO2, Erbium, UltraClear, Other |
| Energy and Device Treatments | Laser Resurfacing (Non-Ablative) | Halo, Fraxel, Moxi, Clear + Brilliant, Icon 1540, ResurFX, AgeJET, Other |
| Energy and Device Treatments | Skin Resurfacing | Microneedling, AquaGold, Dermaplaning, Microdermabrasion, HydraFacial, DiamondGlow, Other |
| Energy and Device Treatments | Pigment and Vascular | IPL, BBL, Vbeam, Nd:YAG, Other |
| Energy and Device Treatments | Light Therapy | Red Light, PDT, Blue Light, Other |
| Energy and Device Treatments | RF Microneedling | Morpheus8, Sylfirm X, Potenza, Vivace, Genius, Exion, Other |
| Energy and Device Treatments | Skin Tightening | Aerolase, Ultherapy, Sofwave, Thermage, Exilis, Pelleve, ThermiSmooth, SkinTyte, FaceTite, AccuTite, Other |
| Energy and Device Treatments | Sweat Reduction | MiraDry, Other |
| Energy and Device Treatments | Acne Therapy | AviClear, Other |
| Energy and Device Treatments | Tattoo Removal | PicoSure, Picoway, Q-Switch, Other |
| Energy and Device Treatments | Other | Other |
| Body Contouring (Non-Surgical) | Fat Reduction | CoolSculpting, SculpSure, Vanquish, Kybella, Other |
| Body Contouring (Non-Surgical) | Muscle Stimulation | Emsculpt, CoolTone, TruSculpt Flex, Other |
| Body Contouring (Non-Surgical) | Cellulite Reduction | BodyTite, Venus Legacy, Emtone, Qwo, Other |
| Body Contouring (Non-Surgical) | Other | Other |
| Clinical Aesthetics | Facials | Oxygen, Acne Facial, Extractions, Other |
| Clinical Aesthetics | Chemical Peels | PCA, VI, BioRePeel, TCA, Glycolic, Jessner, Other |
| Clinical Aesthetics | Hair Removal (Non-Laser) | Waxing, Sugaring, Threading, Other |
| Clinical Aesthetics | Lashes, Brows, and Permanent Makeup | Microblading, Lip Blushing, Lamination, Tints, Permanent Makeup, Other |
| Clinical Aesthetics | Other | Piercing, Spray Tanning, Other |
| Wellness and Hormones | Medical Weight Loss | Semaglutide, Tirzepatide, Phentermine, Other |
| Wellness and Hormones | Hormone Therapy | BioTE Pellets, Testosterone, HRT Management, Other |
| Wellness and Hormones | IV and Vitamin Therapy | Myers Cocktail, NAD+, B12/MIC Shots, Other |
| Wellness and Hormones | Sexual Wellness | O-Shot, P-Shot, Emsella, Empower, MonaLisa Touch, ThermiVa, Diva, Other |
| Wellness and Hormones | Spa | Chiropractic, Acupuncture, Massage, Scrubs, Other |
| Wellness and Hormones | Other | Peptides, Other |
| Hair Restoration | Restoration | PRP, PRF, KeraLase, TED, Other |
| Hair Restoration | Other | Other |
| Consults & Follow Ups | Consults | Aesthetic Consult, Surgical Consult, Other |
| Consults & Follow Ups | Follow Ups | Aesthetic Follow Up, Surgical Follow Up, Other |
| Medical and General | Dermatology | Mole Removal, Skin Tags, Cyst Excision, Kenalog, Other |
| Medical and General | Add-Ons | Numbing, Pronox, Nitrous Oxide, Other |
| Medical and General | Diagnostics | Biopsies, Pathology, Labs, Genetic Testing, Other |
| Medical and General | Conditions | Acne Consults, Rosacea, Eczema, Hyperhidrosis Consults, Other |
| Medical and General | Other | Other |
| Admin | Admin Fees | Booking Deposits, Cancellation Fees, No Show Fees, Other |
| Admin | Non-Revenue | Gift Card, Package, Membership, Tips, Donations, Other |
| Admin | Misc | Shipping, Taxes, Training, Events, Other |
| Admin | Other | Other |
| Fees | Anaesthesia | Anaesthesia, Other |
| Fees | OR Fees | OR Fees, Facility Fees, Other |
channel (leads)
3rd Party, Email, Entity Med, Events, Google, Meta, Organic Search, Other,
Phone, Referral, Returning Patient, Social Media, Walk-in, WebsiterevenueCategory (appointments, revenue-entries) is MedSpa or Surgery.
channel on campaigns, revenueCategory on campaigns and leads, status, paymentMethod, and paymentCategory on payments, and region on clinics are free-form strings.
Permissions
Each key holds read scopes:
| Scope | Endpoint |
|---|---|
banners:read |
/banners |
clinics:read |
/clinics |
employees:read |
/employees |
patients:read |
/patients |
appointments:read |
/appointments |
revenue_entries:read |
/revenue-entries |
payments:read |
/payments |
campaigns:read |
/campaigns |
leads:read |
/leads |
A key may be restricted to clinics or banners. A restricted key sees appointments, revenue entries, and payments for its clinics (a granted banner includes all of its clinics), banners containing at least one of those clinics, and the campaigns and leads of those banners. Employees and patients are organization-wide; for a restricted key, patient lifetimeRevenue and firstRevenueDate are null.
Endpoints
Every list endpoint accepts updatedSince, limit, and cursor. /banners and /clinics also accept id and bannerId. Any other query parameter returns 400 invalid_request.
Every resource serves one record at GET /v1/{resource}/{id}. The seven connection-scoped resources also accept ?connectionId= on that lookup; if an id matches records from more than one connection, the lookup returns 400 invalid_request with the candidate connectionIds in error.details.
GET /access
Returns the key's context. Requires no scope.
| Field | Type | Notes |
|---|---|---|
keyId |
string | Key identifier. |
name |
string | Key display name. |
environment |
string | live or test. |
organization.id |
string | |
organization.name |
string | |
scopes |
string[] | Granted read scopes. |
clinicIds |
integer[] | Clinic restrictions. Empty with bannerIds means unrestricted. |
bannerIds |
integer[] | Banner restrictions. |
connections[].connectionId |
string | The connectionId carried by that connection's records. |
connections[].platform |
string | Source system, e.g. zenoti. |
connections[].label |
string | Name given to the connection. null if none. |
connections[].status |
string | active, pulling, pending, requested, or disabled. A disabled connection's records are not served. |
rateLimit.requestsPerMinute |
integer | |
rateLimit.requestsPerDay |
integer | |
expiresAt |
timestamp | null if the key does not expire. |
{
"data": {
"keyId": "ak_123",
"name": "Customer warehouse sync",
"environment": "live",
"organization": { "id": "example-clinics", "name": "Example Clinics" },
"scopes": ["appointments:read", "revenue_entries:read"],
"clinicIds": [12, 18],
"bannerIds": [],
"connections": [
{ "connectionId": "int_9f8c2b415d3e4a17", "platform": "zenoti", "label": "Austin clinics", "status": "active" },
{ "connectionId": "int_4a1e7c0b8d62f350", "platform": "gohighlevel", "label": null, "status": "active" }
],
"rateLimit": { "requestsPerMinute": 120, "requestsPerDay": 50000 },
"expiresAt": null
}
}GET /sync-status
Returns resource and latestSyncAt for each resource the key can read. See Sync Status.
GET /banners
Scope: banners:read
| Parameter | Description |
|---|---|
id |
One or more banner ids, repeated. Maximum 100. |
updatedSince |
Inclusive lower bound on updatedAt. |
| Field | Type |
|---|---|
id |
integer |
name |
string |
createdAt |
timestamp |
updatedAt |
timestamp |
{
"id": 3,
"name": "Austin MedSpa Group",
"createdAt": "2024-01-08T00:00:00Z",
"updatedAt": "2026-05-02T17:41:09Z"
}GET /clinics
Scope: clinics:read
| Parameter | Description |
|---|---|
id |
One or more clinic ids, repeated. Maximum 100. |
bannerId |
One or more banner ids, repeated. |
updatedSince |
Inclusive lower bound on updatedAt. |
| Field | Type | Notes |
|---|---|---|
id |
integer | |
name |
string | |
bannerId |
integer | |
address.line1 |
string | |
address.city |
string | |
address.state |
string | |
address.postalCode |
string | |
address.country |
string | |
region |
string | |
currency |
string | |
timezone |
string | IANA name, e.g. America/Chicago. The zone of the clinic's appointment times. |
createdAt |
timestamp | |
updatedAt |
timestamp |
{
"id": 12,
"name": "Main Street Clinic",
"bannerId": 3,
"address": {
"line1": "123 Main Street",
"city": "Austin",
"state": "TX",
"postalCode": "78701",
"country": "US"
},
"region": "Southwest",
"currency": "USD",
"timezone": "America/Chicago",
"createdAt": "2024-01-08T00:00:00Z",
"updatedAt": "2026-05-02T17:41:09Z"
}GET /employees
Scope: employees:read
| Field | Type | Notes |
|---|---|---|
id |
string | |
connectionId |
string | |
fullName |
string | |
active |
boolean | |
role |
string | Enumerated. null if unassigned. |
firstActivityDate |
date | |
createdAt |
timestamp | null. |
updatedAt |
timestamp | |
deletedAt |
timestamp | Set when deleted at the source. |
{
"id": "4821",
"connectionId": "int_9f8c2b415d3e4a17",
"fullName": "Jane Smith",
"active": true,
"role": "Nurse Injector",
"firstActivityDate": "2024-03-12",
"createdAt": null,
"updatedAt": "2026-05-12T14:30:00Z",
"deletedAt": null
}GET /patients
Scope: patients:read
| Field | Type | Notes |
|---|---|---|
id |
string | |
connectionId |
string | |
firstName |
string | |
lastName |
string | |
fullName |
string | |
gender |
string | Enumerated. |
dateOfBirth |
date | |
email |
string | |
homePhone |
string | As recorded at the source. |
mobilePhone |
string | As recorded at the source. |
firstActivityDate |
date | |
firstRevenueDate |
date | null for restricted keys. |
lifetimeRevenue |
money | null for restricted keys. |
createdAt |
timestamp | null. |
updatedAt |
timestamp | |
deletedAt |
timestamp | Set when deleted at the source. |
{
"id": "7734",
"connectionId": "int_9f8c2b415d3e4a17",
"firstName": "Dana",
"lastName": "Whitfield",
"fullName": "Dana Whitfield",
"gender": "Female",
"dateOfBirth": "1985-07-02",
"email": "dana.whitfield@example.com",
"homePhone": null,
"mobilePhone": "5551234567",
"firstActivityDate": "2024-03-12",
"firstRevenueDate": "2024-03-20",
"lifetimeRevenue": "1250.00",
"createdAt": null,
"updatedAt": "2026-05-12T14:30:00Z",
"deletedAt": null
}GET /appointments
Scope: appointments:read
| Field | Type | Notes |
|---|---|---|
id |
string | |
connectionId |
string | |
date |
date | Clinic-local business date. |
clinicId |
integer | |
employeeId |
string | null if unassigned. |
patientId |
string | null if unassigned. |
startTime |
clinic-local time | |
endTime |
clinic-local time | |
durationHours |
decimal | |
status |
string | Enumerated. |
parentCategory |
string | Enumerated. |
subCategory |
string | Enumerated. |
serviceCategory |
string | Enumerated. |
revenueCategory |
string | MedSpa or Surgery. |
createdAt |
clinic-local time | When booked. |
updatedAt |
timestamp | |
deletedAt |
timestamp | Set when deleted at the source. |
{
"id": "90114",
"connectionId": "int_9f8c2b415d3e4a17",
"date": "2026-05-12",
"clinicId": 12,
"employeeId": "4821",
"patientId": "7734",
"startTime": "2026-05-12T14:00:00",
"endTime": "2026-05-12T15:00:00",
"durationHours": "1.00",
"status": "completed",
"parentCategory": "Injectables",
"subCategory": "Neurotoxins",
"serviceCategory": "Botox",
"revenueCategory": "MedSpa",
"createdAt": "2026-04-28T09:12:00",
"updatedAt": "2026-05-12T14:30:00Z",
"deletedAt": null
}GET /revenue-entries
Scope: revenue_entries:read
| Field | Type | Notes |
|---|---|---|
id |
string | |
connectionId |
string | |
date |
date | Business date. |
clinicId |
integer | |
employeeId |
string | null if unassigned. |
patientId |
string | null if unassigned. |
invoiceId |
string | Groups the entries of one invoice. |
revenue |
money | |
total |
money | |
quantity |
decimal | |
discount |
money | |
tax |
money | |
parentCategory |
string | Enumerated. |
subCategory |
string | Enumerated. |
serviceCategory |
string | Enumerated. |
revenueCategory |
string | MedSpa or Surgery. |
createdAt |
timestamp | null. |
updatedAt |
timestamp | |
deletedAt |
timestamp | Set when deleted at the source. |
{
"id": "552310",
"connectionId": "int_9f8c2b415d3e4a17",
"date": "2026-05-12",
"clinicId": 12,
"employeeId": "4821",
"patientId": "7734",
"invoiceId": "INV-88213",
"revenue": "950.00",
"total": "1000.00",
"quantity": "1.00",
"discount": "50.00",
"tax": "0.00",
"parentCategory": "Injectables",
"subCategory": "Neurotoxins",
"serviceCategory": "Botox",
"revenueCategory": "MedSpa",
"createdAt": null,
"updatedAt": "2026-05-12T14:30:00Z",
"deletedAt": null
}GET /payments
Scope: payments:read
| Field | Type | Notes |
|---|---|---|
id |
string | |
connectionId |
string | |
status |
string | |
total |
money | |
paymentDate |
date | Business date. |
effectiveDate |
date | Accounting date. |
paymentMethod |
string | |
paymentCategory |
string | |
clinicId |
integer | |
patientId |
string | |
createdAt |
timestamp | |
updatedAt |
timestamp | |
deletedAt |
timestamp | Set when deleted or voided at the source. |
{
"id": "771204",
"connectionId": "int_9f8c2b415d3e4a17",
"status": "paid",
"total": "1000.00",
"paymentDate": "2026-05-12",
"effectiveDate": "2026-05-12",
"paymentMethod": "Credit Card",
"paymentCategory": "Patient Payment",
"clinicId": 12,
"patientId": "7734",
"createdAt": "2026-05-12T14:05:00Z",
"updatedAt": "2026-05-12T14:30:00Z",
"deletedAt": null
}GET /campaigns
Scope: campaigns:read
One row per campaign per day. impressions, clicks, and spend are that day's totals.
| Field | Type | Notes |
|---|---|---|
id |
string | One campaign on one day. |
connectionId |
string | |
channel |
string | |
campaignId |
string | The same across a campaign's days. |
campaignName |
string | |
date |
date | The day the metrics cover. |
startTime |
timestamp | Campaign start. |
endTime |
timestamp | Campaign end. |
impressions |
integer | |
clicks |
integer | |
spend |
money | |
bannerId |
integer | |
revenueCategory |
string | |
createdAt |
timestamp | null. |
updatedAt |
timestamp |
{
"id": "98431:2026-05-12",
"connectionId": "int_9f8c2b415d3e4a17",
"channel": "Meta",
"campaignId": "98431",
"campaignName": "Spring Botox Promo",
"date": "2026-05-12",
"startTime": "2026-04-01T07:00:00Z",
"endTime": "2026-06-30T07:00:00Z",
"impressions": 18420,
"clicks": 322,
"spend": "415.77",
"bannerId": 33,
"revenueCategory": "MedSpa",
"createdAt": null,
"updatedAt": "2026-05-13T06:15:00Z"
}GET /leads
Scope: leads:read
| Field | Type | Notes |
|---|---|---|
id |
string | |
connectionId |
string | |
contactId |
string | CRM contact. |
patientId |
string | null until matched to a patient. |
patientConnectionId |
string | Connection of the matched patient. null when patientId is null. |
employeeId |
string | null if unassigned. |
bannerId |
integer | |
channel |
string | Enumerated. |
campaignId |
string | Joins to campaignId on /campaigns. null if unattributed. |
firstAttribution |
string | Source's first-touch value. |
lastAttribution |
string | Source's last-touch value. |
revenueCategory |
string | |
isExistingPatient |
boolean | |
firstCallDate |
timestamp | null if never called. |
createdAt |
timestamp | Capture time. |
updatedAt |
timestamp | |
deletedAt |
timestamp | Set when deleted at the source. |
{
"id": "c8841",
"connectionId": "int_4a1e7c0b8d62f350",
"contactId": "crm-55102",
"patientId": "7734",
"patientConnectionId": "int_9f8c2b415d3e4a17",
"employeeId": "4821",
"bannerId": 33,
"channel": "Meta",
"campaignId": "98431",
"firstAttribution": "Facebook Lead Ad",
"lastAttribution": "Facebook Lead Ad",
"revenueCategory": "MedSpa",
"isExistingPatient": false,
"firstCallDate": "2026-05-12T16:42:00Z",
"createdAt": "2026-05-12T14:05:00Z",
"updatedAt": "2026-05-13T06:15:00Z",
"deletedAt": null
}Errors
{
"error": {
"code": "invalid_request",
"message": "limit must be between 1 and 5000",
"requestId": "req_abc123",
"details": {
"field": "limit"
}
}
}requestId matches the X-Request-Id header. details is present when there is more to say.
| Status | Code | Meaning |
|---|---|---|
400 |
invalid_request |
Unknown parameter, malformed value, unknown connectionId, or an ambiguous single-record id. |
400 |
invalid_cursor |
Cursor is invalid, expired, or does not match the request. |
401 |
unauthenticated |
Missing, invalid, expired, or revoked API key. |
403 |
forbidden |
Key lacks the required scope. |
404 |
not_found |
Record does not exist or is outside the key's access. |
429 |
rate_limited |
Rate limit exceeded. |
500 |
internal_error |
Unexpected server error. |
503 |
service_unavailable |
Service temporarily unavailable. |
504 |
request_timeout |
Request exceeded 30 seconds. Reduce limit. |
Rate Limits
| Limit | Default |
|---|---|
| Requests per minute | 120 |
| Requests per day | 50,000 |
Your key's limits are in GET /access. Every response carries the per-minute window:
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 93
X-RateLimit-Reset: 1778600000X-RateLimit-Reset is the epoch second when the minute window ends. Exceeding either limit returns 429 rate_limited with a Retry-After header in seconds.
Versioning
/v1 may gain fields, enum values, optional query parameters, and endpoints without a version change. Breaking changes use a new major version path.