curl --request POST \
--url https://api.proofage.net/v1/verifications \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--header 'X-HMAC-Signature: <api-key>' \
--data '
{
"callback_url": "<string>",
"external_id": "<string>",
"external_metadata": {},
"metadata": {}
}
'import requests
url = "https://api.proofage.net/v1/verifications"
payload = {
"callback_url": "<string>",
"external_id": "<string>",
"external_metadata": {},
"metadata": {}
}
headers = {
"X-API-Key": "<api-key>",
"X-HMAC-Signature": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-API-Key': '<api-key>',
'X-HMAC-Signature': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
callback_url: '<string>',
external_id: '<string>',
external_metadata: {},
metadata: {}
})
};
fetch('https://api.proofage.net/v1/verifications', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.proofage.net/v1/verifications",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'callback_url' => '<string>',
'external_id' => '<string>',
'external_metadata' => [
],
'metadata' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>",
"X-HMAC-Signature: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.proofage.net/v1/verifications"
payload := strings.NewReader("{\n \"callback_url\": \"<string>\",\n \"external_id\": \"<string>\",\n \"external_metadata\": {},\n \"metadata\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("X-HMAC-Signature", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.proofage.net/v1/verifications")
.header("X-API-Key", "<api-key>")
.header("X-HMAC-Signature", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"callback_url\": \"<string>\",\n \"external_id\": \"<string>\",\n \"external_metadata\": {},\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.proofage.net/v1/verifications")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["X-HMAC-Signature"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"callback_url\": \"<string>\",\n \"external_id\": \"<string>\",\n \"external_metadata\": {},\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body{
"id": "550e8400-e29b-41d4-a716-446655440000",
"external_id": "user-123",
"external_metadata": {
"plan": "premium"
},
"redirect_url": "https://example.com/callback",
"status": "created",
"reason": null,
"duplicate_check": {
"checked": false,
"duplicate_count": 0,
"duplicates": []
},
"erasure": null,
"consent_accepted_at": null,
"created_at": "2026-03-19T12:00:00+00:00",
"updated_at": "2026-03-19T12:00:00+00:00",
"url": "https://idv.proofage.net/v/eyJ..."
}{
"code": "PAYMENT_METHOD_REQUIRED",
"message": "A payment method is required to create verifications.",
"free_verifications_remaining": 0,
"trial_ends_at": "2026-04-03T12:00:00+00:00",
"trial_active": false
}{
"message": "<string>",
"errors": {}
}Create a verification session
Creates a new verification session and returns a URL for the end-user to complete verification.
curl --request POST \
--url https://api.proofage.net/v1/verifications \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--header 'X-HMAC-Signature: <api-key>' \
--data '
{
"callback_url": "<string>",
"external_id": "<string>",
"external_metadata": {},
"metadata": {}
}
'import requests
url = "https://api.proofage.net/v1/verifications"
payload = {
"callback_url": "<string>",
"external_id": "<string>",
"external_metadata": {},
"metadata": {}
}
headers = {
"X-API-Key": "<api-key>",
"X-HMAC-Signature": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-API-Key': '<api-key>',
'X-HMAC-Signature': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
callback_url: '<string>',
external_id: '<string>',
external_metadata: {},
metadata: {}
})
};
fetch('https://api.proofage.net/v1/verifications', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.proofage.net/v1/verifications",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'callback_url' => '<string>',
'external_id' => '<string>',
'external_metadata' => [
],
'metadata' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>",
"X-HMAC-Signature: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.proofage.net/v1/verifications"
payload := strings.NewReader("{\n \"callback_url\": \"<string>\",\n \"external_id\": \"<string>\",\n \"external_metadata\": {},\n \"metadata\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("X-HMAC-Signature", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.proofage.net/v1/verifications")
.header("X-API-Key", "<api-key>")
.header("X-HMAC-Signature", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"callback_url\": \"<string>\",\n \"external_id\": \"<string>\",\n \"external_metadata\": {},\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.proofage.net/v1/verifications")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["X-HMAC-Signature"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"callback_url\": \"<string>\",\n \"external_id\": \"<string>\",\n \"external_metadata\": {},\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body{
"id": "550e8400-e29b-41d4-a716-446655440000",
"external_id": "user-123",
"external_metadata": {
"plan": "premium"
},
"redirect_url": "https://example.com/callback",
"status": "created",
"reason": null,
"duplicate_check": {
"checked": false,
"duplicate_count": 0,
"duplicates": []
},
"erasure": null,
"consent_accepted_at": null,
"created_at": "2026-03-19T12:00:00+00:00",
"updated_at": "2026-03-19T12:00:00+00:00",
"url": "https://idv.proofage.net/v/eyJ..."
}{
"code": "PAYMENT_METHOD_REQUIRED",
"message": "A payment method is required to create verifications.",
"free_verifications_remaining": 0,
"trial_ends_at": "2026-04-03T12:00:00+00:00",
"trial_active": false
}{
"message": "<string>",
"errors": {}
}Authorizations
Your workspace public key (pk_test_… or pk_live_…).
HMAC-SHA256 of the request, hex-encoded, keyed with the workspace secret key. See API authentication.
Body
Where the person's browser is sent after the final screen, an http or https URL. Ignored unless the request is HMAC-signed.
2048Your identifier for the person. Ignored unless the request is HMAC-signed: the public key alone cannot tie a session to your user.
255Free-form data returned in the API and webhooks. Accepted without a signature, so treat it as client-supplied.
Show child attributes
Show child attributes
Free-form data kept on the session and not returned to integrations.
Show child attributes
Show child attributes
Response
The verification session, with the url the person opens to complete it.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes