Developer docs
Two ways in. Your deployed APIs answer plain HTTPS calls made with a project key. Your workspace (the graph, your tables, entity models, missions and APIs) answers any AI assistant that speaks the Model Context Protocol.
Start here
1.Authentication
Every call carries a project key in the X-API-KEY header. Create keys in your project under API management. A key belongs to one project, can be limited to some of its APIs, and has a monthly request limit.
X-API-KEY: sk-your-key-here
Keep keys out of URLs and out of code that runs in a browser: anyone who can see a key can use it, and the calls are billed to your account.
2.Calling an API
Open the API in Enact and copy its endpoint: your project's service address followed by /api/run/<api id>. Send the input as the JSON body of a POST.
curl -X POST "https://<your service>/api/run/<api id>" \
-H "X-API-KEY: sk-your-key-here" \
-H "Content-Type: application/json" \
-d '{"prompt": "A product photo of a ceramic mug"}'The body is the API's input itself. To continue a conversation or to label calls in your analytics, wrap it instead: input holds the input, session_id continues a session, tracking_id labels the call.
{
"input": {
"prompt": "A product photo of a ceramic mug"
},
"session_id": "my-session-1",
"tracking_id": "order-1042"
}A successful answer carries the call's calculated cost in the X-Api-Cost header and the time it took in X-Api-Latency-Ms.
3.Errors
An error answers with a status code and a JSON body with a detail field: a sentence, or an object with error and message.
| Status | What it means |
|---|---|
400 | The API refused the input. detail says why. |
401 | No key was sent. |
402 | Not enough credit, or your plan's monthly usage is used up. detail.error is payment_required, detail.message says what to do and detail.billing_url where. |
403 | The key is not valid, or it may not call this API. |
404 | There is no API with this id on this service. |
429 | Too many calls in a short time (wait the number of seconds in Retry-After), or the key's monthly request limit is reached. |
500 to 504 | Something failed on our side or at a model provider. Try again after a pause. |
{
"detail": {
"error": "payment_required",
"message": "...",
"billing_url": "/settings?tab=billing"
}
}4.Limits
- Rate: each key has a short-term rate limit. Above it a call answers
429with aRetry-Afterheader in seconds. - Monthly requests: each key has a monthly request limit, set per key under API management. Past it calls answer
429until the next month. - Request size: a request body can be at most 32 MiB. Put larger files in storage first and pass a link.
- Time: call your service's own address for long work. The enqualia.io website closes a request after about 60 seconds; the service itself waits for the API to finish.
5.Long-running work
Work in the workspace that takes minutes (missions, ingests, model training) starts a job and answers with its id at once. Follow it with the same key until status is succeeded or failed. Over MCP the same jobs are the get_job tool.
curl "https://enqualia.io/api/qualia/<project id>/jobs/<job id>" \ -H "X-API-KEY: sk-your-key-here"