Create magic link

PUBLIC

Starts the magic link login flow for an end user. Sends a one-time login link
to the provided email address. The link contains a challenge token to be passed
to POST /auth/link/verify.

Events fired

EventTriggerDescription
authorization.CodeIssuedsyncFired when the magic link code is successfully issued.
Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…
📘

Eventsauthorization.CodeIssued

Why this endpoint exists

Session exchange works when your customers are already signed in on your platform. When they are not — a standalone storefront, a campaign where you have no accounts of your own — the platform has to establish identity itself.

It does that with a magic link: the customer types their e-mail, receives a one-time link, clicks it, and lands back on your storefront with a session. No password to create, remember or reset.

If you have your own accounts, use session exchange instead. It is fewer steps for the customer, has no e-mail deliverability risk, and does not depend on someone reading their inbox mid-purchase.

Request

curl -X POST https://api.acc.funtrips.io/v2/auth/link/create \
  -H "x-campaign-id: $CAMPAIGN_ID" \
  -H "Accept-Language: nl-NL" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "callback_url": "https://tickets.your-brand.example/auth/callback",
    "query_params": { "returnTo": "/merchant/amsterdam-zoo" },
    "integrator_params": { "tier": "gold" }
  }'
FieldTypeRequiredNotes
emailemailYesWhere the link is sent
callback_urluriNoWhere the link points. Must be permitted for the campaign
query_paramsobjectNoString values appended to the callback URL
integrator_paramsobjectNoOpaque values carried on the session JWT. Max 2 KiB encoded

callback_url must be allowed

The platform appends the challenge token and session to this URL. It is validated against the campaign's configured hosts — an unregistered URL is rejected with user-no-callback-url, because otherwise the endpoint would be an open redirect that mails attacker-controlled links to arbitrary addresses.

Register your callback hosts with us before you use them. Omit the field and the campaign's default is used.

query_params preserves intent

Values here are appended to the callback URL, so the customer returns to where they were rather than to your homepage. Put the product or merchant they were looking at in here — the round trip through an inbox is exactly where purchase intent gets lost.

integrator_params rides on the session

An opaque map carried as a single integrator_params claim on every subsequent authenticated request, consumed by downstream infrastructure such as partner loyalty mirroring. The API never interprets the keys.

Keep the JSON-encoded total within 2 KiB — it is on the JWT, and an oversized claim breaks every request the session makes.

Response

200 OK — the link has been e-mailed.

{
  "data": { "expires_in_seconds": 900 },
  "meta": { "correlation_id": "…" }
}

expires_in_seconds is how long the emailed token stays valid. Show it: "we sent you a link, it works for 15 minutes" sets the right expectation and cuts support contacts.

The response says nothing about the customer

A 200 means we accepted the request and sent an e-mail. It does not mean the address exists, is deliverable, or belongs to a real customer.

That is on purpose: an endpoint that reported "no such user" would let anyone enumerate your customer base one address at a time. So the response is identical for a known and an unknown address, and your UI must say "check your inbox" rather than anything that implies the account was found.

Localisation

The e-mail body is localised from Accept-Language, negotiated against the campaign's supported locales, with your campaign's branding applied on top. Send the customer's language — this e-mail is often their first contact with the storefront.

Errors

StatustypeWhat to do
400email missing or malformed
400user-no-callback-urlcallback_url is not permitted for this campaign
400campaign-not-foundUnknown campaign
502user-magic-link-send-failedThe e-mail could not be sent. Retryable
500Unexpected fault. Retryable

A 502 is the one to surface: the customer is waiting for an e-mail that will never arrive. Offer a "resend" affordance rather than leaving them on "check your inbox".

Next step

The customer clicks the link, arrives at your callback_url with a token in the query string, and your front-end posts it to POST /auth/link/verify.

Notes

  • Rate-limit your own form. An open e-mail field is an abuse vector — it can be driven to mail-bomb a third party. Debounce submissions and cap attempts per address before calling this endpoint.
  • authorization.CodeIssued is published when the code is issued.
Body Params

Initiates the magic link login flow for an end user.

Headers
Responses

Language
URL
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json
application/problem+json