VerifyFirst API Documentation
Introduction & Authentication
The VerifyFirst API lets you integrate blockchain-based document timestamping, verification, revocation, and expiration webhooks directly into your application. All requests require an API key provided in the X-VerifyFirst-Key HTTP header. Each key is bounded by a monthly usage quota.
Base URL
https://api.verifyfirst.com.au/verifyfirst/v1
Authentication Header
Authorization:
X-VerifyFirst-Key: your_api_key_here
All endpoints return JSON responses. Errors use standard HTTP status codes and include a JSON body with an error field.
1. Timestamp API
Create a new timestamp proof. You can upload a file (e.g., PDF, DOCX, JPG) or, if you support hash-only mode, supply a precomputed SHA-256 hash. Optionally include a cover letter (PDF) and set an expiration period in months.
Endpoint
POST /timestamp
Request Headers
Content-Type:multipart/form-dataX-VerifyFirst-Key: Your API key (string)
Request Body (multipart/form-data)
- file (required if no
file_hash): The document to be timestamped. - file_hash (string, required if no
file): Precomputed SHA-256 hex digest of the file. Use only if your frontend hashes the document. - cover_letter (optional): A PDF file to attach as a cover letter.
- VerifyFirst hashes this file separately and anchors both proofs.
- months (optional, integer): Number of months until expiration.
- Example:
6for six months.
- Example:
- customer_id (optional, integer): Your internal customer identifier.
- If omitted, defaults to
0.
- If omitted, defaults to
Example (curl—file upload)
curl -X POST "https://api.verifyfirst.com.au/verifyfirst/v1/timestamp" \
-H "X-VerifyFirst-Key: YOUR_API_KEY" \
-F "file=@/path/to/document.pdf" \
-F "cover_letter=@/path/to/cover.pdf" \
-F "months=12" \
-F "customer_id=42"
Example (curl—hash-only mode)
curl -X POST "https://api.verifyfirst.com.au/verifyfirst/v1/timestamp" \
-H "X-VerifyFirst-Key: YOUR_API_KEY" \
-F "file_hash=abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" \
-F "months=6" \
-F "customer_id=42"
Response (201 Created)
{
"id": 1234,
"file_hash": "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
"filename": "document.pdf",
"ots_file": "abcdef1234567890.ots",
"timestamp_created": "2025-06-01T14:23:45+10:00",
"duration_months": 12,
"expiry_date": "2026-06-01",
"customer_id": 42,
"explorer_url1": "https://blockstream.info/tx/txid_here",
"explorer_url2": "https://blockchain.com/explorer/tx/txid_here"
}
Error Responses
400 Bad Request—Missing required fields or invalid file/hash.401 Unauthorized—Invalid or missing API key.429 Too Many Requests—Monthly quota exceeded.500 Internal Server Error—Unexpected server error.
2. Verify API
Check whether a given document (or proof file) has been anchored on the Bitcoin blockchain. The Verify endpoint validates by looking up the stored hash and checking the blockchain status.
Endpoint
GET /verify/{file_hash}
Request Headers
X-VerifyFirst-Key: Your API key (string)
Path Parameters
- file_hash (string, required): SHA-256 hex digest of the document or cover letter.
Example (curl)
curl -X GET "https://api.verifyfirst.com.au/verifyfirst/v1/verify/abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" \
-H "X-VerifyFirst-Key: YOUR_API_KEY"
Response (200 OK)
{
"file_hash": "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
"status": "confirmed",
"timestamp_created": "2025-06-01T14:23:45+10:00",
"confirmed_at": "2025-06-02T03:17:12+10:00",
"bitcoin_block": 840512,
"txid": "txid_here",
"explorer_url1": "https://blockstream.info/tx/txid_here",
"explorer_url2": "https://blockchain.com/explorer/tx/txid_here"
}
Error Responses
400 Bad Request—Malformed file_hash (not a 64-character hex).404 Not Found—No timestamp found for that hash.401 Unauthorized—Invalid API key.
3. Revoke API
Invalidate a previously created proof. Once revoked, any future verification attempts will return "status": "revoked". A revocation transaction is recorded on-chain to preserve transparency.
Endpoint
POST /revoke
Request Headers
Content-Type:application/jsonX-VerifyFirst-Key: Your API key (string)
Request Body (JSON)
{
"file_hash": "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
}
Example (curl)
curl -X POST "https://api.verifyfirst.com.au/verifyfirst/v1/revoke" \
-H "Content-Type: application/json" \
-H "X-VerifyFirst-Key: YOUR_API_KEY" \
-d '{
"file_hash": "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
}'
Response (200 OK)
{
"file_hash": "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
"status": "revoked",
"revoked_at": "2025-06-10T09:45:00+10:00",
"revocation_txid": "revocation_txid_here"
}
Error Responses
400 Bad Request—Missing or invalidfile_hash.404 Not Found—No existing timestamp to revoke.401 Unauthorized—Invalid API key.409 Conflict—Timestamp already revoked.
4. Notification Webhook API
Configure webhooks to receive JSON callbacks before or on the expiration date of a timestamp. When a document is within the configured days_before of expiration, VerifyFirst sends an HTTP POST to your delivery_url with event details.
Create a Webhook
POST /webhooks
Request Headers
Content-Type:application/jsonX-VerifyFirst-Key: Your API key (string)
Request Body (JSON)
{
"customer_id": 42,
"event_type": "expiry",
"delivery_url": "https://yourapp.example.com/webhook-handler",
"days_before": 7
}
Fields Description:
- customer_id (integer, required) — Your internal ID that matches the timestamp’s
customer_id. - event_type (string, required) — Always
"expiry"for expiration alerts. - delivery_url (string, required) — HTTPS URL where VerifyFirst will POST JSON when the event occurs.
- days_before (integer, required) — Number of days before
expiry_dateto trigger the notification.
Example (curl)
curl -X POST "https://api.verifyfirst.com.au/verifyfirst/v1/webhooks" \
-H "Content-Type: application/json" \
-H "X-VerifyFirst-Key: YOUR_API_KEY" \
-d '{
"customer_id": 42,
"event_type": "expiry",
"delivery_url": "https://yourapp.example.com/webhook-handler",
"days_before": 7
}'
Response (201 Created)
{
"id": 789,
"customer_id": 42,
"event_type": "expiry",
"delivery_url": "https://yourapp.example.com/webhook-handler",
"days_before": 7,
"last_fired": null,
"created_at": "2025-06-01T15:00:00+10:00"
}
Error Responses
400 Bad Request—Missing required fields or invalid URL.401 Unauthorized—Invalid API key.409 Conflict—Webhook with identicalcustomer_id,event_type, anddays_beforealready exists.
Webhook Callback Payload
When the expiration event triggers, VerifyFirst POSTs the following JSON to your delivery_url:
{
"event": "expiry",
"days_before": 7,
"file_hash": "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
"filename": "document.pdf",
"expiry_date": "2026-06-01"
}
Fields Description:
- event (string) — Always
"expiry"for expiration notifications. - days_before (integer) — The configured lead time for this notification.
- file_hash (string) — SHA-256 hash of the document.
- filename (string) — Original filename submitted during timestamping.
- expiry_date (string, YYYY-MM-DD) — The date the document expires.
List All Webhooks
GET /webhooks?customer_id={customer_id}
Request Headers
X-VerifyFirst-Key: Your API key
Query Parameters
- customer_id (integer, required) — Filter webhooks by your customer ID.
Example (curl)
curl -X GET "https://api.verifyfirst.com.au/verifyfirst/v1/webhooks?customer_id=42" \
-H "X-VerifyFirst-Key: YOUR_API_KEY"
Response (200 OK)
[
{
"id": 789,
"customer_id": 42,
"event_type": "expiry",
"delivery_url": "https://yourapp.example.com/webhook-handler",
"days_before": 7,
"last_fired": "2025-05-25T15:00:00+10:00",
"created_at": "2025-06-01T15:00:00+10:00"
},
{
"id": 790,
"customer_id": 42,
"event_type": "expiry",
"delivery_url": "https://another.example.com/notify",
"days_before": 3,
"last_fired": null,
"created_at": "2025-06-02T10:00:00+10:00"
}
]
Delete a Webhook
DELETE /webhooks/{id}
Request Headers
X-VerifyFirst-Key: Your API key
Path Parameters
- id (integer, required) — The unique ID of the webhook to delete.
Example (curl)
curl -X DELETE "https://api.verifyfirst.com.au/verifyfirst/v1/webhooks/789" \
-H "X-VerifyFirst-Key: YOUR_API_KEY"
Response (204 No Content)
Successfully deleted. No response body.
Error Responses
404 Not Found—Webhook ID not found for your account.401 Unauthorized—Invalid API key.
