A submission is only accepted with a signature, issued by the platform to the visitor's browser. The website's secret key never leaves Rikochey: it is neither in the script nor in any API response.
GET /api/websites/{website}/signature
| Check | Value |
|---|---|
| Authentication | none; the page's Origin is authoritative |
| Origin | the Origin header must match the website's host |
| Rate limiting | api-signature, 30 per minute per IP |
| Cache | Cache-Control: no-store — never cached, at any level |
Response 200
{
"signature": "7c1f9a2e…",
"timestamp": 1789459200,
"expires_in": 600
}
| Field | Purpose |
|---|---|
signature |
To put in the X-Website-Signature header of the submission |
timestamp |
To put in X-Website-Timestamp; both go together |
expires_in |
Validity period, in seconds |
Errors
| Code | Body | Cause |
|---|---|---|
403 |
{"error": "origin_not_allowed"} |
The Origin does not match the website's host |
404 |
{"message": "Website not found."} |
Unknown UUID |
429 |
— | More than 30 requests per minute from the same address |
How the script uses it
It keeps the signature in memory and only requests a new one when less than 60 seconds of validity remain. A page left open for a long time therefore gets a fresh signature at submission time, with no needless request in between.
On a 403 invalid_signature at submission, it discards the stored signature, requests a
new one, and retries once only: this is the case of a website key regenerated while
the visitor was filling in the form. A second refusal is not retried.
What it protects, and what it does not
The signature ties a submission to a website and to a point in time. It prevents a captured request from being replayed indefinitely, and prevents posting to a website from a third-party page.
It is not a proof of humanity: an Origin header can be forged outside a browser. It
is the combination — short lifetime, rate limiting at the edge then in the application,
captcha — that keeps automated submissions in check.
API