KEYXE Developer Center · API
KEYXE API Reference.
This page documents only what the KEYXE Worker actually implements, plus planned routes that are intentionally disabled. There are no public data endpoints and no Amazon data endpoints.
Status
The API runs on Cloudflare Workers with a D1 database and is intended to be served at https://api.keyxe.net. Routes are built and covered by automated tests. Production availability depends on deployment, domain routing, bot-protection keys and email notification setup.
Conventions
- JSON in, JSON out (
application/json; charset=utf-8), bodies up to 32 KiB. - Browser-only intake: POST requests must come from an allowed
Origin(production:https://keyxe.net). - Every form submission is verified server-side with Cloudflare Turnstile and rate-limited.
- Optional
Idempotency-Keyheader makes retries safe: the same key and payload return the original response. - Every response includes an
X-Request-Idheader andCache-Control: no-store. - A case reference (such as
KXC-…) is for correspondence only. It is not a credential, and there is no endpoint to look up a case by reference.
GET /v1/health
Liveness check. Returns no secrets or configuration details. Alias: /api/health.
GET https://api.keyxe.net/v1/health
200 OK
{ "status": "ok", "service": "keyxe-api", "version": "0.1.0", "environment": "production" }GET /v1/public/site-config
Non-secret feature states (the same registry that drives every status chip on this website) and the operator name.
POST /v1/contact
Creates a contact case after validation, bot verification and rate limiting. Fields: fullName, email, optional company, topic (general, sp_api, ads_api, mcp_developers, pricing, open_source, for_humanity, security_privacy), message, privacyAck, turnstileToken.
POST https://api.keyxe.net/v1/contact
Origin: https://keyxe.net
Content-Type: application/json
Idempotency-Key: 6f1c2b8e-4a1f-4c2e-9d55-0b7f1f3e2a10
{
"fullName": "Avery Example",
"email": "[email protected]",
"company": "Example Co.",
"topic": "ads_api",
"message": "We would like to learn about the advertising workspace.",
"privacyAck": true,
"turnstileToken": "<token from the Turnstile widget>"
}201 Created
{
"ok": true,
"reference": "KXC-7M2Q9V4K1D",
"status": "received",
"notification": "not_configured",
"requestId": "0b6a…"
}notification reports the team email separately from storage: sent, failed or not_configured. A 201 always means the case was stored.
422 Unprocessable Content
{
"ok": false,
"error": {
"code": "VALIDATION_FAILED",
"message": "Some fields need attention.",
"fields": { "email": "Enter a valid email address." },
"requestId": "0b6a…"
}
}POST /v1/security-reports
Confidential intake for vulnerabilities, privacy concerns and incidents. Fields: optional reporterName and email, subject, category (vulnerability, privacy, incident, other), optional severity, description, optional affectedUrl and reproduction, consent, turnstileToken. The response contains only a KXS- reference. Team notifications never include the report text.
POST /v1/data-requests
Records an access, correction, deletion or other privacy request. Fields: optional fullName, email, requestType, optional details, privacyAck, turnstileToken. Nothing is deleted automatically: identity is verified by a person before any action, and the request is never displayed publicly.
Planned, disabled routes
These paths are reserved for future Amazon authorization and answer truthfully until an approved, secured implementation exists. Seller (SP-API) and advertising (Ads API) routes are separate code paths with separate callbacks.
/v1/auth/sp-api/start,/v1/auth/sp-api/callback,/v1/connections/sp-api/v1/auth/ads/start,/v1/auth/ads/callback,/v1/connections/ads
GET https://api.keyxe.net/v1/auth/sp-api/start
503 Service Unavailable (no redirect, no Location header)
{ "ok": false, "error": { "code": "APPROVAL_PENDING", "message": "…", "requestId": "…" } }No MCP endpoint and no customer application exist. mcp.keyxe.net and app.keyxe.net are not published.
Error codes
| HTTP | Code | Meaning |
|---|---|---|
| 400 | INVALID_JSON | The body is not valid JSON. |
| 403 | ORIGIN_NOT_ALLOWED | Missing or unlisted Origin header. |
| 403 | TURNSTILE_FAILED | Bot-protection token invalid, expired, reused, or for another hostname/action. |
| 404 | NOT_FOUND | Unknown path. |
| 405 | METHOD_NOT_ALLOWED | Known path, wrong method (see the Allow header). |
| 409 | IDEMPOTENCY_CONFLICT | Idempotency-Key reused with a different payload. |
| 413 | PAYLOAD_TOO_LARGE | Body over 32 KiB. |
| 415 | UNSUPPORTED_MEDIA_TYPE | Content-Type is not application/json. |
| 422 | VALIDATION_FAILED | Field errors in error.fields. |
| 429 | RATE_LIMITED | Too many submissions; see Retry-After. |
| 500 | INTERNAL_ERROR | Storage or unexpected failure. Nothing is claimed as stored. |
| 503 | SERVICE_NOT_CONFIGURED | Required production configuration is missing. |
| 503 | SERVICE_UNAVAILABLE | Bot-protection verification could not be reached. |
| 503 | APPROVAL_PENDING | Amazon integration routes (not yet approved). |