Skip to main content
Mobile attribution receipts are part of the Public Beta. Verify them only on trusted backend infrastructure.
A matched live mobile-open response can contain attributionReceipt, a compact JSON Web Token (JWT) signed with Ed25519. Use it as short-lived evidence when a referral can grant money, credit, access, or another valuable benefit. Never trust only the referral code, click ID, or decoded JWT body. A client can modify those values unless your backend verifies the signature and claims.

Retrieve the JSON Web Key Set

Example:
This JSON Web Key Set (JWKS) endpoint returns an ETag and Cache-Control: public, max-age=3600. Cache the set for up to one hour, use conditional requests with If-None-Match, and refresh immediately once if an otherwise valid receipt uses an unknown kid. Do not pin a single key forever; key rotation can expose multiple verification keys. The endpoint returns 404 when receipt verification is not available.

Header contract

Require every header value: Select only a JWK with kty: OKP, use: sig, alg: EdDSA, and crv: Ed25519. Decode its x member as the 32-byte Ed25519 public key and verify the compact JWT signature over the original encoded header and payload segments. Do not accept an algorithm from application input, fall back to another algorithm, or treat a decoded payload as verified.

Claim contract

Use a small, documented clock-skew allowance when checking nbf, iat, and exp. Never extend exp locally.

Idempotent reward flow

1

Receive the live receipt

Send it from the app to your authenticated backend immediately after the matched resolver response. Use TLS and do not place it in a URL.
2

Verify cryptography and claims

Verify the Ed25519 signature, fixed header values, issuer, audience, time claims, app, link, match type, and confidence before reading referral data.
3

Apply your own eligibility rules

Confirm the signed referral is valid for the authenticated user, campaign, product, geography, and operation. A valid receipt proves Biqli attribution, not your business eligibility.
4

Consume jti atomically

In the same transaction that grants the reward, insert jti into a unique consumed-receipt store. If it already exists, return the original outcome instead of granting again.
Success means the reward and receipt ID commit once. A network retry with the same receipt returns the previously recorded result.

PHP verification outline

Use a maintained JOSE library that supports EdDSA and OKP JWKs when possible. If your implementation uses Sodium directly, the critical signature operation is equivalent to:
This outline deliberately does not provide storage or authorization logic. Your backend must implement atomic replay prevention and business eligibility.

Failure handling

Reject the receipt when:
  • it has other than three compact segments;
  • decoding, JSON parsing, or Ed25519 verification fails;
  • the algorithm, type, key type, curve, use, or key ID is unexpected;
  • issuer, audience, app, workspace, link, click, or open does not match the operation;
  • it is early, expired, or unreasonably future-dated;
  • jti was already consumed for a different operation; or
  • your policy does not accept the match type or confidence.
A missing receipt is normal for none, for a cached SDK result, or when receipts are unavailable. It is not evidence that should bypass verification.