Authentication
Create and rotate mak_ API keys, give each one the scopes it needs, cap its spending, and let a browser poll with a pat_ token.
Every request sends one credential as Authorization: Bearer <credential> to
https://api.mynth.io. Which credential you send depends on where the code
runs:
| Where the code runs | Credential | Reaches |
|---|---|---|
| Your server | mak_... | Every endpoint the key's scopes allow |
| A browser | pat_... | GET /tasks/{id}/status and /result for one task |
| mynth.io | OAuth | The dashboard and playground. Your code never sends this. |
The API key is the only credential you create and store. The pat_ token is
issued with each task. The API reference
has the header rules, the scope each endpoint needs, CORS, and every
authentication error.
npx @mynthio/cli auth login
npx @mynthio/cli api-key create my-appPOST /api-keys needs a key with the keys scope. In the
dashboard, the new key appears once in a dialog, next to
a ready-made MYNTH_API_KEY=mak_... line.
The key is shown once. The create response carries it at data.raw, and no
endpoint returns it again. Mynth stores only an HMAC-SHA256 of the key, so a
lost key cannot be recovered. Lists show key_preview, such as mak_9d4...e3f.
A key is mak_ followed by 48 hex characters. An account can hold 100 live
keys. Deleted keys do not count toward that.
The SDK and the CLI both read MYNTH_API_KEY. In the CLI it takes precedence
over the key stored by auth login.
GET /me accepts any key and describes it. npx @mynthio/cli whoami prints
the same thing.
curl https://api.mynth.io/me -H "Authorization: Bearer $MYNTH_API_KEY"{
"data": {
"user_id": "user_01JD8G3W1R5T6Y7U8I9O0P1Q2W",
"auth": {
"method": "api-key",
"api_key": {
"id": "ak_01KE7XWWEQ4MCGWKBQKJ1G47RP",
"name": "my-app",
"key_preview": "mak_9d4...e3f",
"scopes": ["generate"],
"spending": { "mode": "unlimited" }
}
}
}
}Run it first when a request fails with 401 or 403.
A key carries one or more scopes. New keys get generate unless you ask for
more.
| Scope | Reaches |
|---|---|
generate | /image/*, /video/*, /tasks/*, /me |
manage | /webhooks, /destinations, /balance, /me |
keys | /api-keys, /me |
Give a key only what its job needs. A leaked generate key can spend your
balance. It cannot create keys, read your balance, or point a webhook
somewhere else.
You can change a key's scopes later, on its page in the
dashboard or with PUT /api-keys/{id}. The change applies
to the next request.
An API key cannot grant manage or keys. When the caller authenticates
with an API key, POST /api-keys and PUT /api-keys/{id} accept only
["generate"] and answer anything wider with 403 scope_escalation. Create
or widen those keys in the dashboard. The key auth login creates is the
exception: it is minted through the browser approval and gets all three
scopes by default.
Create a second key, deploy it, then delete the first. Both keys work during the switch. Deleting a key revokes it immediately.
A key can carry a USD cap that resets each day, week, or calendar month in UTC.
Weekly caps reset on Monday and follow ISO weeks across year boundaries. Set
it on the key's page in the dashboard, or send spending_limit and
spending_limit_period to PUT /api-keys/{id}. The create call does not take
one.
spending_limit is a decimal string of US dollars with at most two decimal
places, such as "25.00", and spending_limit_period is day, week, or
month. A limit needs a period, and "spending_limit": null with no period
removes the cap. The update replaces the key's settings, so send scopes and
spending_limit every time.
The cap counts each task's estimate when the task is created. Once the next
estimate would pass the cap, creating a task fails with
402 spending_limit_exceeded until the period rolls over. A task that fails
later does not give its estimate back to the cap. GET /me reports used,
limit, and remaining for a capped key.
POST /image/generate, POST /image/remove-background,
POST /image/upscale, and POST /video/generate return
data.public_access_token, a pat_ token for that one task, when the request
sets generate_public_access_token: true. It works only on GET /tasks/{id}/status and
GET /tasks/{id}/result for that task, and it expires one hour after it is
issued.
Create the task on your server, give the browser the task id and the token, and poll from the page. Poll for results has the code, and the reference has every rule.
Never ship a mak_ key to the browser. Only the two polling paths allow cross-origin requests, so
a key in a page cannot generate from that page, but anyone can read it from the bundle and spend
your balance from anywhere else.
whsec_ secret, separate from your key.