API Documentation | VerifyFirst

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-data
  • X-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: 6 for six months.
  • customer_id (optional, integer): Your internal customer identifier.
    • If omitted, defaults to 0.

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/json
  • X-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 invalid file_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/json
  • X-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_date to 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 identical customer_id, event_type, and days_before already 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.
Scroll to Top