πŸ”’ Private beta β€” we’re finalizing our qualified eIDAS electronic seal. Request early access β†’
Developer Β· REST API

Automate digital content certification via the API

The InstantProof REST API lets you certify any public URL programmatically. Authenticate with a Bearer API key, POST a URL, and receive a signed certificate PDF with a full evidence bundle β€” the same RFC 3161 timestamp and Ed25519 signature as the web interface.

RESTJSON over HTTPS
BearerAPI key auth
RFC 3161Qualified timestamps
API certification illustration

Capturing many URLs? Check coverage first.

Some sites serve bot-protection (a captcha or human-verification check) that can block an automated capture β€” cookie/consent banners are auto-dismissed and do not block it. We detect a real block on every capture and never bill a blocked one (the API returns 422 bot_protection_blocked with an assistedCaptureUrl). A blocked URL can still be captured with assisted capture, where a person clears the challenge before the page is certified. Test a target domain before you batch.

Test a domain β†’

Prerequisites

1
Pro plan or higherThe API requires the Pro subscription (api_access feature). Subscribe here.
2
An API keyCreate one at Settings β†’ API keys. Copy the key immediately β€” it is shown only once.
3
An https:// URL to certifyThe API certifies publicly reachable web pages. The URL must be a valid https:// address.

Quick-start

Three steps from zero to a signed certificate PDF.

Step 1 β€” Create an API key

Log in, go to Developer β†’ API keys, and click Create API key. Copy the key β€” it is shown only once.

Step 2 β€” Create a certificate

Send a POST request with your URL:

curl -X POST https://secure.instantproof.legal/api/v1/certificates \
  -H "Authorization: Bearer ip_live_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/page-to-certify"}'

Response 201 Created:

{
  "certificateId": "abc123…",
  "recordingId":   "def456…",
  "url":           "https://example.com/page-to-certify",
  "finalUrl":      "https://example.com/page-to-certify",
  "status":        "ready",
  "links": {
    "self":        "/api/v1/certificates/def456…",
    "certificate": "/api/v1/certificates/def456…/download"
  }
}

Step 3 β€” Download the certificate PDF

Follow the links.certificate URL with your API key. The server returns a 302 redirect to a pre-signed download URL:

curl -L \
  -H "Authorization: Bearer ip_live_xxxxxxxxxxxxxxxx" \
  "https://secure.instantproof.legal/api/v1/certificates/def456…/download" \
  -o certificate.pdf

The downloaded PDF is the same signed certificate PDF that the web UI produces, verifiable at /certificate.html.

API reference

Base URL: https://secure.instantproof.legal
All endpoints return JSON. Authentication: Authorization: Bearer <key>.

POST /api/v1/certificates

Create a new website certificate. The platform captures the URL in a headless browser, produces a HAR network log and screenshot, signs the manifest with Ed25519, and anchors to a qualified RFC 3161 timestamp. The operation takes 10–60 seconds.

Request body (JSON)

FieldTypeDescription
urlstringrequiredA valid https:// URL to certify. Must be publicly reachable.

Response 201 Created

FieldTypeDescription
certificateIdstringHuman-readable certificate ID (shown on the PDF).
recordingIdstringInternal recording UUID. Use in subsequent API calls.
urlstringThe URL you submitted.
finalUrlstringThe URL after any redirects, as seen by the browser.
statusstring"ready" β€” the certificate is immediately available.
links.selfstringPath to fetch this certificate's metadata.
links.certificatestringPath to download the PDF. Requires auth.

Error responses

StatuserrorMeaning
400invalid_urlThe url field is missing or not a valid https:// address.
400invalid_jsonRequest body is not valid JSON.
401invalid_api_keyMissing or invalid Authorization header.
402api_access_requiredYour account does not have the Pro plan. Subscribe.
403subscription_requiredWeb certificates require a flat-rate subscription.
403insufficient_scopeThe API key lacks the certificates:write scope.
413payload_too_largeRequest body exceeds 64 KB.
429quota_exceededDaily API capture quota reached. Resets every day.
429rate_limitedToo many requests. See Retry-After header.
429service_busyCapture service at capacity. Retry after ~30 seconds.
502capture_failedThe browser could not load the URL.
502certification_failedCapture produced no usable evidence (e.g. empty HAR).

GET /api/v1/certificates/:recordingId

Retrieve metadata for a certificate you previously created.

Path parameters

ParameterDescription
recordingIdrequiredThe recordingId returned by POST /api/v1/certificates.

Response 200 OK

FieldTypeDescription
certificateIdstringHuman-readable certificate ID.
recordingIdstringInternal recording UUID.
typestringRecording type (e.g. "webcapture").
statusstring"ready" once the certificate is available.
urlstringThe URL that was certified.
createdAtstringISO 8601 creation timestamp.
linksobjectself and certificate paths.

GET /api/v1/certificates/:recordingId/download

Download the signed certificate PDF. Returns 302 Found β€” follow the redirect to receive the file. Use curl -L or requests.get(..., allow_redirects=True).

Authentication

All API requests must include:

Authorization: Bearer ip_live_xxxxxxxxxxxxxxxx

Keys are created at Settings β†’ Developer β†’ API keys. A key authenticates as your account β€” treat it like a password. Revoke immediately if leaked.

Keys are prefixed ip_live_ for live accounts. The prefix helps you identify them in code or environment files.

Rate limits & quotas

~30

Requests per minute

30 requests/minute sustained (burst: 30). Exceeding returns 429 rate_limited with a Retry-After header.

Daily

Daily capture quota

The Pro plan grants a fixed number of certificate creations per day. The quota resets every day. Exceeding it returns 429 quota_exceeded.

64 KB

Request body limit

The JSON request body must not exceed 64 KB. In practice, a URL is well under this limit.

Code examples

Python

import requests

API_KEY = "ip_live_xxxxxxxxxxxxxxxx"
BASE    = "https://secure.instantproof.legal"

# Create a certificate
resp = requests.post(
    f"{BASE}/api/v1/certificates",
    json={"url": "https://example.com"},
    headers={"Authorization": f"Bearer {API_KEY}"},
)
resp.raise_for_status()
data = resp.json()
recording_id = data["recordingId"]

# Download the PDF
pdf = requests.get(
    f"{BASE}/api/v1/certificates/{recording_id}/download",
    headers={"Authorization": f"Bearer {API_KEY}"},
    allow_redirects=True,
)
pdf.raise_for_status()
with open("certificate.pdf", "wb") as f:
    f.write(pdf.content)
print(f"Certificate saved ({len(pdf.content)} bytes)")

Node.js (fetch)

const API_KEY = process.env.INSTANTPROOF_API_KEY;
const BASE    = "https://secure.instantproof.legal";

// Create a certificate
const res = await fetch(`${BASE}/api/v1/certificates`, {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ url: "https://example.com" }),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const { recordingId, links } = await res.json();

// Download the PDF
const pdf = await fetch(`${BASE}${links.certificate}`, {
  headers: { "Authorization": `Bearer ${API_KEY}` },
  redirect: "follow",
});
const buffer = Buffer.from(await pdf.arrayBuffer());
require("fs").writeFileSync("certificate.pdf", buffer);

Shell (curl)

# Set your key
export INSTANTPROOF_API_KEY="ip_live_xxxxxxxxxxxxxxxx"

# Create
CERT=$(curl -sf -X POST https://secure.instantproof.legal/api/v1/certificates \
  -H "Authorization: Bearer $INSTANTPROOF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com"}')

echo "$CERT" | python3 -m json.tool

RECORDING_ID=$(echo "$CERT" | python3 -c "import sys,json; print(json.load(sys.stdin)['recordingId'])")

# Download
curl -sfL \
  -H "Authorization: Bearer $INSTANTPROOF_API_KEY" \
  "https://secure.instantproof.legal/api/v1/certificates/$RECORDING_ID/download" \
  -o certificate.pdf

ls -lh certificate.pdf

Frequently asked questions

How long does a certificate creation take?

Typically 10–60 seconds, depending on the target page's load time. The POST request blocks until the certificate is ready β€” there is no polling step.

Does the API support file certificates (PDF, image uploads)?

The current API supports website (URL) certification only. File uploads are available via the web interface at secure.instantproof.legal/certificates/new.

Can I verify a certificate created via the API?

Yes. The PDF produced by the API is identical to one created through the web UI. Drag it onto instantproof.legal/certificate.html to verify the Ed25519 signature and RFC 3161 timestamp chain.

What happens if the URL is unreachable?

The capture service returns a 502 capture_failed error. Your daily quota is not consumed.

Are API-created certificates visible in the web dashboard?

Yes. Every certificate created via the API appears in your Certificates dashboard under My Website certificates, alongside any web-interface certificates.