What this API key or OAuth token is allowed to do, from the perspective of the credential itself: its prefix, name, test/live mode, scopes, and expiry; the account's plan; the per-minute and per-day request limits with what is left of each (both enforced per ACCOUNT, not per key); whether this request's RFC 9421 signature verified and the rate multiplier it bought; and the spend controls — per-order cap, daily cap, and how much of today's is already committed. Read-only: it reserves nothing and moves no tally. Call it before planning a run rather than discovering the same limits as a 403, a 429, or a spend_cap_exceeded on an order you had already decided to place. Requires no scope — a credential can always describe itself — but does consume one request from both rate windows, which is why the numbers it reports are the ones remaining after this call. Fields that cannot be read (a spend ledger blip) come back null rather than zero.
- Credential
- An API key in
x-api-key - Scopes
- None: every key may call it
Request
GET /api/v1/me
curl "https://portal.printedsimply.com/api/v1/me" \
-H "x-api-key: ps_test_YOUR_KEY"Response 200
Credential scopes, limits, and spend controls
data
keyobjectrequiredkey.prefixstringThe key's public prefix. Never the key itself.
key.namestring | nullkey.modestringOne of
testlivekey.scopesstring[]key.expires_atstring (date-time) | nullaccountobjectrequiredaccount.planstringaccount.plan_labelstringrate_limitsobjectrequiredBoth windows are enforced per ACCOUNT, not per key — minting more keys does not buy more throughput, and
scopesays so rather than leaving it to be inferred from a per-key-looking response.rate_limits.scopestringAlways
accountrate_limits.requests_per_minuteobjectrate_limits.requests_per_minute.limitintegerrequiredrate_limits.requests_per_minute.remainingintegerrequiredrate_limits.requests_per_minute.resetintegerrequiredWhen the window resets, as a Unix timestamp in milliseconds (the same value as X-RateLimit-Reset).
rate_limits.requests_per_dayobjectThe same fields as
rate_limits.requests_per_minuteverified_agentobjectrequiredsignedis what the request claimed;verifiedis what checked out. Only the second buys the rate multiplier, and an agent debugging its own signature needs to see the two disagree.verified_agent.signedbooleanverified_agent.verifiedbooleanverified_agent.key_idstring | nullverified_agent.agent_namestring | nullverified_agent.rate_multipliernumberverified_agent.reasonstring | nullWhy the signature did not verify. Null when it verified, and when the request carried none.
spend_controlsobjectrequiredspend_controls.per_order_cap_centsinteger | nullspend_controls.daily_cap_centsinteger | nullspend_controls.daystringspend_controls.spent_today_centsinteger | nullReserved against the daily cap so far today. Null when the key has no daily cap, or when the day's tally could not be read.
spend_controls.remaining_today_centsinteger | nullapi_versionstringrequiredThe version this response was served under — the same value as the
MF-Versionheader.
meta
pageintegertotalintegerlimitintegerThe page size actually applied, which is not necessarily the one asked for — the operation's own ceiling wins.
pagesintegertotaloverlimit, rounded up.next_cursorstring | nullOn a cursor-paged operation: send this back as
cursorfor the next page. Null on the last page. Absent on operations that do not page by cursor.has_morebooleanOn a list operation whose
metaisListMeta: whether another page follows this one.
{
"status": "success",
"data": {
"key": {
"prefix": "mf_test_xxxxxxxx",
"name": "Examples",
"mode": "test",
"scopes": [
"all"
],
"expires_at": null
},
"account": {
"plan": "starter",
"plan_label": "Free"
},
"rate_limits": {
"scope": "account",
"requests_per_minute": {
"limit": 60,
"remaining": 60,
"reset": 1792076462000
},
"requests_per_day": {
"limit": 10000,
"remaining": 10000,
"reset": 1792108800000
}
},
"verified_agent": {
"signed": false,
"verified": false,
"key_id": null,
"agent_name": null,
"rate_multiplier": 1,
"reason": null
},
"spend_controls": {
"per_order_cap_cents": null,
"daily_cap_cents": null,
"day": "2026-10-15",
"spent_today_cents": null,
"remaining_today_cents": null
},
"api_version": "2026-07-26"
},
"request_id": "4e3753e1-48dd-4313-bfd8-48e4af4e116a"
}Errors
Missing, invalid or expired API key:
missing_api_key(none sent),invalid_api_key(unknown or revoked),key_expired(past the expiry set when it was created; create a new key).Rate limit exceeded. Two windows can produce this status and
error.codesays which:rate_limit_exceededfor the per-minute sliding window,daily_quota_exceededfor the plan's daily quota. Both carryRetry-After; the daily one also carriesX-Daily-LimitandX-Daily-Remaining. The per-minute limits are plan-based — see Rate Limits above, or call GET /v1/me for this credential's own figures.