Create a gift link (browser)
const url = 'https://your-tenant-host/edgekit/v1/gift-links';const options = { method: 'POST', headers: {'x-edgekit-site-id': 'site_example', 'Content-Type': 'application/json'}, body: '{"content":{"payload":"{\"article_id\":\"a-1\",\"section\":\"news\",\"paywall_level\":\"2\"}","signature":"example"},"context":{"additionalProperty":"example"},"userId":"0199a4c2-7b1e-7c3d-9a4f-2e8b5d6c1a90","expiresInDays":1}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://your-tenant-host/edgekit/v1/gift-links \ --header 'Content-Type: application/json' \ --header 'x-edgekit-site-id: site_example' \ --data '{ "content": { "payload": "{\"article_id\":\"a-1\",\"section\":\"news\",\"paywall_level\":\"2\"}", "signature": "example" }, "context": { "additionalProperty": "example" }, "userId": "0199a4c2-7b1e-7c3d-9a4f-2e8b5d6c1a90", "expiresInDays": 1 }'Evaluates the tenant’s gift-link create feature for the gifter and this page, charging its meters, and mints a token only on allow. A deny is 200 with the create feature’s decision. 401 on the browser route when no user is signed in, 404 when gifting is not configured, 422 when the page carries no value for the tenant’s key fact. Same rate limits as POST /decide. Not idempotent: every call charges the quota and mints a new link — retry only a request that got no answer.
Parameters
Section titled “Parameters”Header Parameters
Section titled “Header Parameters”The site this request is for, within this tenant. Every official EdgeKit SDK sets it from the client you configured; set it yourself only when calling this API directly.
Example
site_exampleThe site this request is for, within this tenant. Every official EdgeKit SDK sets it from the client you configured; set it yourself only when calling this API directly.
Request Bodyrequired
Section titled “Request Bodyrequired”object
object
The content descriptor, serialised. Signed as these exact bytes — there is no canonicalisation step, because a canonicalising scheme is a second parser that has to agree with the first.
Example
{"article_id":"a-1","section":"news","paywall_level":"2"}Base64url HMAC-SHA256 of payload under this site’s content key.
Unverified, as on decide. The link’s content_key may bind to a context.* fact; the view rule, reading the viewed page, is the gate.
object
The gifter. Keyed route only, refused (403) on /edgekit/v1/gift-links. Absent on the keyed route mints an internal gift link.
Example
0199a4c2-7b1e-7c3d-9a4f-2e8b5d6c1a90A shorter life than the tenant’s TTL, never longer. Keyed route only, refused (403) on the browser route.
Responses
Section titled “Responses”Created, or denied by the create feature.
object
created carries token and expiresAt; denied is the create feature answering no. Open: treat a member not listed as not created.
The signed gift-link token, for the ?_gt parameter. created only.
When the token stops opening anything. created only.
object
The id the site switches on.
The winning outcome’s own named fields, flattened to plain JSON — never a stringified blob. Absent for a plain outcome, where the id is the whole answer. A ref field resolves to a curated catalog object (never a bare id) carrying exactly the keys its select named.
Present iff the matched outcome declared one. allow/deny is an access verdict; redirect names a destination (see GET /decide/forward); data is neither. Open: accept a member not listed.
The meter reads this feature’s rules made, keyed by meter name, as read — before this request’s own ticks. allowance - count is what was left going in. Absent when no rule read a meter.
object
object
Example
{ "status": "created", "expiresAt": "2026-10-10T12:00:00.000Z", "decision": { "type": "allow" }}Invalid request.
object
object
Example
{ "error": { "code": "unauthorized", "message": "Invalid or missing API key." }}Missing or invalid credential.
object
object
Example
{ "error": { "code": "unauthorized", "message": "Invalid or missing API key." }}Not allowed.
object
object
Example
{ "error": { "code": "unauthorized", "message": "Invalid or missing API key." }}Resource not found.
object
object
Example
{ "error": { "code": "unauthorized", "message": "Invalid or missing API key." }}Request body too large.
object
object
Example
{ "error": { "code": "unauthorized", "message": "Invalid or missing API key." }}Request validation failed.
object
object
Example
{ "error": { "code": "unauthorized", "message": "Invalid or missing API key." }}Too many requests. Retry-After says when to retry.
object
object
Example
{ "error": { "code": "unauthorized", "message": "Invalid or missing API key." }}Unexpected error.
object
object
Example
{ "error": { "code": "unauthorized", "message": "Invalid or missing API key." }}With Retry-After, briefly unavailable; without it, not configured.
object
object
Example
{ "error": { "code": "unauthorized", "message": "Invalid or missing API key." }}