Skip to content

Create a gift link (browser)

POST
/edgekit/v1/gift-links
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.

x-edgekit-site-id
required

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.

string
>= 1 characters <= 128 characters

Example

site_example

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.

Media typeapplication/json
object
content
object
payload
required

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.

string
>= 1 characters

Example

{"article_id":"a-1","section":"news","paywall_level":"2"}
signature
required

Base64url HMAC-SHA256 of payload under this site’s content key.

string
>= 1 characters
context

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
key
additional properties
userId

The gifter. Keyed route only, refused (403) on /edgekit/v1/gift-links. Absent on the keyed route mints an internal gift link.

string format: uuid
>= 1 characters

Example

0199a4c2-7b1e-7c3d-9a4f-2e8b5d6c1a90
expiresInDays

A shorter life than the tenant’s TTL, never longer. Keyed route only, refused (403) on the browser route.

integer
>= 1

Created, or denied by the create feature.

Media typeapplication/json
object
status
required

created carries token and expiresAt; denied is the create feature answering no. Open: treat a member not listed as not created.

string
token

The signed gift-link token, for the ?_gt parameter. created only.

string
expiresAt

When the token stops opening anything. created only.

string format: date-time
decision
required
object
outcome
required

The id the site switches on.

string | null
value

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.

type

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.

string
reason
required
string
reasonDetail
string
meters

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
key
additional properties
object
count
required
integer
allowance
required
integer

Example

{
"status": "created",
"expiresAt": "2026-10-10T12:00:00.000Z",
"decision": {
"type": "allow"
}
}

Invalid request.

Media typeapplication/json
object
error
required
object
code
required
string
message
required
string
details

Example

{
"error": {
"code": "unauthorized",
"message": "Invalid or missing API key."
}
}

Missing or invalid credential.

Media typeapplication/json
object
error
required
object
code
required
string
message
required
string
details

Example

{
"error": {
"code": "unauthorized",
"message": "Invalid or missing API key."
}
}

Not allowed.

Media typeapplication/json
object
error
required
object
code
required
string
message
required
string
details

Example

{
"error": {
"code": "unauthorized",
"message": "Invalid or missing API key."
}
}

Resource not found.

Media typeapplication/json
object
error
required
object
code
required
string
message
required
string
details

Example

{
"error": {
"code": "unauthorized",
"message": "Invalid or missing API key."
}
}

Request body too large.

Media typeapplication/json
object
error
required
object
code
required
string
message
required
string
details

Example

{
"error": {
"code": "unauthorized",
"message": "Invalid or missing API key."
}
}

Request validation failed.

Media typeapplication/json
object
error
required
object
code
required
string
message
required
string
details

Example

{
"error": {
"code": "unauthorized",
"message": "Invalid or missing API key."
}
}

Too many requests. Retry-After says when to retry.

Media typeapplication/json
object
error
required
object
code
required
string
message
required
string
details

Example

{
"error": {
"code": "unauthorized",
"message": "Invalid or missing API key."
}
}

Unexpected error.

Media typeapplication/json
object
error
required
object
code
required
string
message
required
string
details

Example

{
"error": {
"code": "unauthorized",
"message": "Invalid or missing API key."
}
}

With Retry-After, briefly unavailable; without it, not configured.

Media typeapplication/json
object
error
required
object
code
required
string
message
required
string
details

Example

{
"error": {
"code": "unauthorized",
"message": "Invalid or missing API key."
}
}