API reference
Run scans and read results from your own code. Available on the Advanced plan.
Last updated 18 September 2026
Authentication
Create a key on the API page and send it as a bearer token:
Authorization: Bearer aw_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
The key is shown once, at the moment it is created. We keep only a hash of it, so nobody — including us — can read it back to you. If you lose it, generate a new one and revoke the old one.
Only Bearer is accepted. Sending the bare key is refused, because every system that logs request headers would then be logging a credential.
Endpoints
| Method | Path | What it does |
|---|---|---|
GET | /api/v1/me | Your plan, your limits, and how much of them you have used in the last 24 hours. |
GET | /api/v1/scans | Recent scans, newest first. ?limit= accepts 1–100 and defaults to 20. |
POST | /api/v1/scans | Run a scan and return it. Long request — the server allows up to 120 seconds. |
GET | /api/v1/scans/{id} | One scan in full, including the text of every answer it is based on. |
Check the key before you spend anything
curl https://mossagents.com/api/v1/me \ -H "Authorization: Bearer $ANSWERWATCH_API_KEY"
Returns your plan, your limits and your usage, without running a scan:
{
"account": { "id": "usr_…", "email": "you@example.com", "plan": "advanced", "planName": "Advanced" },
"limits": { "projects": 10, "promptsPerScan": 20, "engineScope": "all", "scansPerDay": 10 },
"usage": { "projects": 3, "scansLast24h": 1 }
}This endpoint exists so that the usual first question — "is this key working, and what am I entitled to?" — is not answered by running a real scan and paying for it.
Run a scan
curl -X POST https://mossagents.com/api/v1/scans \
-H "Authorization: Bearer $ANSWERWATCH_API_KEY" \
-H 'content-type: application/json' \
-d '{"domain":"acme.com"}'The body accepts:
| Field | Type | Notes |
|---|---|---|
domain | string | Required. The site being measured. |
brandName | string | Optional. How the brand is normally written, when that differs from the domain. |
category | string | Optional. Narrows the generated questions to a market. |
locale | 'en' | 'zh' | Optional. The language the questions are asked in. |
questions | string[] | Optional. Your own buying questions, asked before the generated ones. They are stored on the project, so a later scan without them keeps asking the same set instead of silently reverting to ours. |
webSearch | boolean | Optional. Ask the engines to search the live web, on the engines that can. This changes the bill: a browsing answer costs roughly twenty times one answered from memory, which is why it is something the caller opts into rather than something every scan does quietly. |
Read the result
curl https://mossagents.com/api/v1/scans/scan_xxxxxxxxxxxx \ -H "Authorization: Bearer $ANSWERWATCH_API_KEY"
The stored answer text is the point of this endpoint. Every number in a report is derived from those answers, so you can verify the score yourself rather than trusting it.
Errors
| Status | Meaning |
|---|---|
| 401 | No key, a malformed key, or a key that has been revoked. |
| 403 | The key is fine, but the account is not on Advanced. Do not regenerate the key — change the plan. |
| 402 | The account has reached its project limit for the plan. |
| 429 | This project's daily scan allowance is used up. Resets on a 24-hour window. |
| 404 | No such scan — or it belongs to a different account. |
| 500 | The scan ran but could not be saved. See the note below. |
401 and 403 are deliberately different. An integrator who receives 401 goes and replaces the credential; if a plan problem also returned 401, they would spend an afternoon fixing something that was never wrong.
A scan id belonging to somebody else returns 404, not 403. A 403 would confirm the id exists, which turns the endpoint into a tool for enumerating other customers' scans.
Limits
The API and the dashboard enforce the same numbers from the same table — not two rules that happen to agree today:
- Scans per project per day, by plan (Advanced allows 10). Rolling 24-hour window.
- Questions and engines per scan follow the plan, and the dashboard shows the same ones.
This is deliberate. If the API had its own allowance, the two paths together could exceed what the price covers.
Two things that look odd, and why
A scan is attached to a tracked project. The first time you scan a domain, a project is created for it; later calls reuse it. That costs you a project slot (Advanced allows 10), but it means an API-only customer still gets score history and competitor comparison instead of a one-off snapshot, daily monitoring covers those projects automatically, and both paths write the same rows — so the dashboard and the API cannot contradict each other. Scanning a domain you already track uses no extra project slot.
A failure to save returns 500, not 201. The scan itself is valid even when persistence fails, so it is not thrown away. But a caller that receives an id will come back to read it, and telling you "created" and then returning 404 on the next request is worse than failing now — failing now is at least something a client can see and retry.
A failed engine call is "not measured", never "not mentioned". If an engine does not answer, that is recorded as a gap in the measurement. Counting it as an absence would understate your visibility and blame the wrong thing.
Questions
Limits, behaviour under load, and anything the contract above does not cover — write to us before building around an assumption, and we will answer with the truth about what the code does rather than what we wish it did.