Base URL
{org} is your organization’s runtime subdomain and {project} the project’s slug. Records live under /entities/{entity}/records, where {entity} is the entity’s slug.
Authentication
Full details, including how each credential is scoped: Authentication → Data API.
Creating a project API key
Open the project in the HASP platform and choose API keys in the project’s sidebar. A project admin selects New key, names it, and picks Live or Test; the key’s prefix (hasp_pak_live_ / hasp_pak_test_) records that choice. The full key is shown once, right after it is created — copy it then, because HASP stores only a hash of it and cannot show it again. Every project member can see the key list (name, environment, last four characters, created and last-used dates, status); only project admins can create, rotate, or revoke keys.
- Rotate issues a replacement key immediately. The old key keeps working for 72 hours so an integration can switch over without downtime, then it is revoked automatically.
- Revoke takes effect immediately: the next request with that key fails with
API_KEY_REVOKED.
App-level endpoints
Two endpoints sit beside the project-scoped ones, athttps://{org}.usehasp.run/api/hasp/v1, and are addressed by the X-Hasp-AppId header rather than a project:
GET /bootstrap— the signed-in user, their org and app role, the app, and its Data API limits. Called with the runtime session; apublicapp also answers an anonymous caller. The SDK’sgetBootstrap().GET /status— liveness, callable without credentials. With a project API key it also reports whether an app of the key’s project is in maintenance. The SDK’sgetStatus().
Records
A record is the entity’s declared fields plus three system fields:GET /projects/{project}/schema. The published reference describes records as EntityRecord: the system fields plus additionalProperties, with an x-hasp-entity-schema extension pointing at that schema endpoint — the API spec cannot know your fields, the schema endpoint does.
Writes send field values under data. Keys that are not declared fields are dropped; values are validated against each field’s type and constraints, and a failing field is reported in error.details under its key.
Numbers are stored exactly. A number or currency value that cannot be held exactly — an integer beyond 64 bits, or a decimal with more precision than a double carries — is rejected with 422 rather than rounded. Send large identifiers as text.
Bulk endpoints (/records/bulk) take up to 100 items and are all-or-nothing: every item is written in one transaction, or none is. A failing item is reported at its position — records.3.title, updates.0.id, ids.2.
Filtering, sorting, and pagination
filter— a JSON object of conditions. See Filtering for the syntax and the operators each field type supports.sort—fieldorfield:asc|desc, oncreated_at,updated_at, or any declared non-jsonfield.cursor/pageSize— keyset pagination. See Pagination.
422, never ignored.
Indexing fields
Setindexed: true on a field (the indexed property on the AI API schema field endpoints, POST /v1/projects/{project}/schemas/{entity}/fields and PATCH …/fields/{field}, or indexed: true on a field in Studio’s entity contract) and HASP builds a database index on it. Filters with eq, gt, gte, lt, lte, and in, and sorts on the field, are then served from the index instead of scanning the entity’s records. neq, contains, and starts_with scan regardless.
- Indexable types:
number,currency,date,boolean,enum,reference,email, andphone— types whose values are bounded.text,multiline, andjsoncannot be indexed; the schema API rejectsindexed: trueon them with422. - At most 10 indexed fields per entity. Every index is maintained on every write, so index the fields you filter or sort on routinely — identifiers, statuses, dates — not every field.
- At most 50 indexed fields per organization, across all its projects.
- String values of an indexed field are limited to 255 characters, so they always fit in the index. Turning
indexedon for a field that already holds a longer value is rejected with422; an indexedenum’s allowed values must fit too.
References
Areference field holds the id of a record of another entity, and must declare which entity (constraints.entity_slug). When a record is written, each reference is checked: the target must exist, belong to the declared entity in the same project, and live in the same environment — a production record can only reference production records, and a sandbox record only records in its own sandbox.
References are checked when written, not maintained afterwards. If the referenced record is later deleted, the reference keeps its value; resolve it with a read and treat 404 as “no longer exists”. An update that resends a reference unchanged is not re-checked, so a record whose target was deleted can still be edited.
Errors
Every Data API error — on the app-level endpoints and for every credential type, agent credentials included — uses the same envelope as the AI API:422 VALIDATION_FAILED with every failing field in error.details, keyed by its path. The full code list is in Errors.
Endpoints
The endpoint reference in this section is generated from the platform’s routes intoopenapi/data-v1.json and checked for drift in CI.