Skip to main content

Merchant REST API

The Enterprise merchant API provides a privacy-minimized, cursor-paginated read endpoint for verification records. Credentials are managed in the Developer page (/app/developer) by the Shopify account owner.

Authentication

Bearers authenticate with idgp_v1 tokens. Only a SHA-256 digest is stored; the plaintext token is returned once at creation. Tokens are hashed, revocable, and capped at five active credentials per shop.
The API re-checks the shop’s Enterprise plan and the Merchant API setting on every request.

Endpoints

List verifications

Returns paginated verification records. Status, limit, and cursor are optional query parameters.
Query parameters Response fields per record
  • id — verification identifier
  • customer_id — linked customer identifier, if any
  • provider — provider name (didit, stripe, self_certification)
  • internal_status — current lifecycle status
  • verification_type — verification method
  • minimum_age — minimum age applied for the decision
  • verified_at — timestamp of verification
  • created_at — creation timestamp
  • updated_at — last update timestamp
  • country_code — coarse country code from metadata
  • state_code — coarse state or province code from metadata
  • last_error_code — stable error code (never free-text)
The API never exposes date of birth, contact fields, provider reports, document images, biometrics, or raw provider error text. Supported methods Only GET is supported. Unsupported methods return 405.

Rate limits

Rate limiting is enforced per shop. See the app’s rate-limit configuration for thresholds.

Error response format

Authentication and authorization errors Every request re-checks the API key, the shop’s plan, and the Merchant API setting. A failed check returns an error object with a machine-readable code and a message: All responses include Cache-Control: no-store.

Storefront app proxy

Shopify maps the storefront prefix /apps/age-verification to the app route /api/proxy. Requests are accepted only after the server verifies Shopify’s app-proxy signature, timestamp, shop domain, and path prefix. Use the store-facing path so Shopify generates the signed proxy request:
The POST verify parser accepts countryCode, stateCode, event, dob, and termsAccepted. It also parses customerId and email, but customer linkage uses Shopify’s signed logged_in_customer_id; a client-supplied customer ID is not trusted. Simple mode recognizes event: "simple_verified" and its compact storefront value event: "s". Enhanced success returns the implemented session fields verificationId, clientSecret, redirectUrl, and status; the active provider determines whether clientSecret or redirectUrl is populated. Direct route modules also exist at /api/settings and /api/verify, but they apply the same app-proxy signature check. They are not unsigned alternatives to the storefront proxy.

Embedded-admin identity routes

These routes require an authenticated Shopify admin session and operate only on the authenticated shop’s records. Session creation accepts an optional internal customerId, normalized email, verification type, selfie requirement, ID-number requirement, and allowed document types. The settings record supplies the minimum age.

Shopify POS routes

The POS API requires a Shopify POS session token in Authorization: Bearer .... The server derives the shop from the token’s signed dest claim. The POST body accepts only attachedCustomerId. A pending response contains status, autoSkipped, token, verifyUrl, minimumAge, and pollIntervalMs. An auto-skip response contains status, autoSkipped, and minimumAge.

Incoming webhook routes

Didit is the production-selected identity provider. The Stripe Identity callback route serves the rollback path.

Outbound verification-event webhooks

Pro stores can configure one public HTTPS event-webhook endpoint in Settings. Enterprise stores can also configure an API webhook endpoint, which is sent the same events. The implementation rejects credential-bearing URLs, literal IP targets, localhost, and DNS results that resolve only to private addresses. The app sends JSON with four top-level fields: event, shop, occurredAt, and data. The implemented event names are:
  • identity_verification_started
  • identity_verification_verified
  • identity_verification_requires_input
  • identity_verification_failed
Verify X-Pcnaid-Hmac-Sha256 as HMAC-SHA256 over the raw request body using the read-only signing secret shown in the app’s Settings page. Event names are a fixed set and are not configurable.