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 withidgp_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.
Endpoints
List verifications
Response fields per record
id— verification identifiercustomer_id— linked customer identifier, if anyprovider— provider name (didit,stripe,self_certification)internal_status— current lifecycle statusverification_type— verification methodminimum_age— minimum age applied for the decisionverified_at— timestamp of verificationcreated_at— creation timestampupdated_at— last update timestampcountry_code— coarse country code from metadatastate_code— coarse state or province code from metadatalast_error_code— stable error code (never free-text)
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
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 inAuthorization: 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_startedidentity_verification_verifiedidentity_verification_requires_inputidentity_verification_failed
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.