Skip to main content
If your software is used by many people who each have their own ProofAge account, such as a hosting billing panel, a marketplace plugin or a CMS module, you can give them a Connect ProofAge button instead of asking them to paste keys. The user signs in to ProofAge, picks a workspace and clicks Allow. Your software receives that workspace’s public key and a secret key made for this connection, and from then on it calls the API like any other integration. This page is for platform developers. If you only want to use ProofAge from your own site, see the quick start and the server SDKs.

Get a client ID

Connecting needs a client_id that ProofAge registers for your app. There is no self-service sign-up: write to [email protected], say what you are building and whether it runs on your users’ own servers or as a hosted service, and we send you the client_id. If you would like to talk about a partnership, mention it in the same message. Everything below runs on the app host, https://app.proofage.net, not on api.proofage.net. The device endpoints refuse requests to any other host. Only the verification calls you make afterwards go to https://api.proofage.net/v1.

The device flow

Your software asks ProofAge for a short code, shows it to the user, and polls until the user has approved it. No redirect URI is involved, so one client_id works on every install.
1

Ask for a code

When the user clicks Connect ProofAge, call:
The scope must be exactly workspace:connect. ProofAge answers 200:
Keep device_code to yourself: it is what you poll with. A code lives for expires_in seconds (10 minutes).A single address may ask for 20 codes a minute. Beyond that the answer is 429 with {"error": "slow_down", …}: wait a minute before asking again. One code per click on Connect ProofAge is plenty.
2

Show the code and the plain link

Show the user the user_code and a link to verification_uri, and ask them to type the code there. Do not link to verification_uri_complete and do not open it for them. ProofAge ignores a code in the address on purpose: the person must type the code that your software is showing them, so a link cannot send them to somebody else’s request. Say so on your screen, for example: Open this page and enter the code. Only enter a code you see here.The user opens the page, signs in to ProofAge (or creates an account and then clicks Connect ProofAge in your software again, because the code lives only 10 minutes), types the code, picks a workspace and clicks Allow. ProofAge shows them the name of your app, the publisher name we registered for it, and a notice headed Check before you allow: allow only if they started this connection in your app themselves, just now. After Allow, the page tells them to go back to your software, which finishes connecting on its own.
3

Poll for the token

While the user does that, call the token endpoint every interval seconds:
Until the user has decided, the answer is an error. Handle these:When the user has approved, the answer is 200:
4

Collect the keys

The access token only proves who connected your app. Use it once, to fetch the keys:
The response is Cache-Control: no-store. The call works once: whatever the outcome, ProofAge then revokes the access token and the refresh token, so do not keep them. Errors come as {"error": {"code": "…"}}:

What to store

Store both keys, per user of your platform (per install, if one install serves one account): the api_key (public) and the secret_key. Treat the secret key like a password. Show the user which workspace is connected, by workspace.name, and say whether it is a test or live workspace with workspace.mode: the user picks the workspace, and a test workspace verifies nothing for real and bills nothing (see Sandbox testing). The secret key is made for this connection and belongs to your software:
  • ProofAge names it Your app · the user’s email · date and marks it Connected via Your app in the workspace’s key list in the console.
  • The console does not show its secret, so it cannot be copied into another system by accident. Only your software has it.
  • It is not the workspace’s active key and cannot be made active. The webhook URL the user set in the console is still signed with their own active key, which your software does not have.
  • ProofAge e-mails the administrators of the user’s organization whenever your app gets a new key, with the workspace, the person who connected and the key’s name.
  • The user disconnects your software by deleting the key in the console. Your next call to /v1 then answers 401. Treat that 401 as disconnected: tell the user and let them connect again. The old key never works again.
A connection is one workspace, your app and one ProofAge user. Connecting the same workspace again with the same ProofAge account returns the same key. A different ProofAge user of the same organization who connects that workspace gets a key of their own. If the user connects again and picks another workspace, you receive that workspace’s keys; the key for the first workspace keeps working until the user deletes it in the console.

Call the API

Sign every /v1 request with the secret key, exactly as in API authentication, with the api_key in X-API-Key. The server SDKs do the signing for you. Create verifications from your server, with a signed request. A create with the public key alone, for example from a browser, has no signature: ProofAge then drops external_id and callback_url, which your software needs to match a verification to its own customer and to bring the person back to your page afterwards. A signed create from your server is also what ties the verification to your app.
Nothing else has to be passed with a request. To be told about decisions, create a webhook subscription with your keys: its deliveries are signed with your secret key, so you can verify them. Do not ask the user to put your URL in the workspace’s webhook setting; that one is signed with their active key. You can also retrieve results by polling. If the user deletes your key, deliveries to your subscription continue, signed with the workspace’s active key; answer 410 to a delivery you cannot verify and ProofAge deletes the subscription.

The scope

The only scope is workspace:connect. With the keys it yields, your software can do what any integration with that workspace’s keys can do through the API: create verifications, read their results, subscribe to webhooks, block a face from a verification and erase a verification’s personal data. It cannot reach the user’s other workspaces or their console. Only administrators and developers of an organization can connect an app; the connect screen refuses anyone else.

The redirect flow, for hosted services

A hosted service with one fixed address (an integration platform such as Zapier) uses the standard OAuth 2.0 authorization code flow instead. You register one redirect URI with us and receive a client_id and a client_secret.
  1. Send the user’s browser to https://app.proofage.net/oauth/authorize with response_type=code, your client_id, your registered redirect_uri, scope=workspace:connect and a state you check on return. The scope is the only one allowed.
  2. The user signs in, picks a workspace and clicks Allow. ProofAge redirects to your redirect_uri with code and state.
  3. Exchange the code at https://app.proofage.net/oauth/token with grant_type=authorization_code, your client_id and client_secret, the redirect_uri and the code.
  4. Call POST https://app.proofage.net/oauth/connect/credentials with the access token, as in step 4 of the device flow. Everything under What to store applies unchanged.
A client of one flow cannot use the other: asking a redirect client for a device code, or a device client for an authorization code, is refused.

Test it

Connect a test workspace while you build. Create a verification with the keys you receive, and set its outcome from the console or with POST /v1/verifications/{id}/test-outcome.

Troubleshooting