API Documentation

Complete reference for the Attestiv REST API. Sign invoices, verify documents, and manage your account programmatically.

Base URL: https://attestiv.io/api/v1 Version: 1.0

Authentication

The Attestiv API uses JWT (JSON Web Tokens) for authentication. Include the token in the Authorization header for all authenticated requests.

POST /auth/token/

Obtain an access token using your credentials.

curl -X POST https://attestiv.io/api/v1/auth/token/ \
  -H "Content-Type: application/json" \
  -d '{
    "username": "your_username",
    "password": "your_password"
  }'

Response

{
  "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
}

Using the token: Include the access token in the Authorization header for authenticated requests: Authorization: Bearer YOUR_ACCESS_TOKEN

POST /auth/token/refresh/

Refresh an expired access token.

curl -X POST https://attestiv.io/api/v1/auth/token/refresh/ \
  -H "Content-Type: application/json" \
  -d '{"refresh": "YOUR_REFRESH_TOKEN"}'

Vendors

Manage vendor accounts, signing keys, and domain verification.

POST /vendors/register/ Public

Register a new vendor account.

curl -X POST https://attestiv.io/api/v1/vendors/register/ \
  -H "Content-Type: application/json" \
  -d '{
    "username": "acme_corp",
    "email": "admin@acme.com",
    "password": "secure_password_123",
    "name": "Acme Corporation",
    "domain": "acme.com"
  }'

Response

{
  "id": "vnd_abc123",
  "name": "Acme Corporation",
  "domain": "acme.com",
  "is_domain_verified": false,
  "created_at": "2026-01-20T10:00:00Z",
  "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
}
GET PUT /vendors/me/ Auth Required

Get or update your vendor profile.

# Get profile
curl https://attestiv.io/api/v1/vendors/me/ \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# Update profile
curl -X PUT https://attestiv.io/api/v1/vendors/me/ \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Acme Corp Inc."}'
POST /vendors/keys/ Auth Required

Create a new Ed25519 signing key for invoice signatures.

# Create a new signing key
curl -X POST https://attestiv.io/api/v1/vendors/keys/ \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Production Key 2026"}'

# List all keys
curl https://attestiv.io/api/v1/vendors/keys/ \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# Revoke a key
curl -X POST https://attestiv.io/api/v1/vendors/keys/KEY_ID/revoke/ \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response (Create Key)

{
  "id": "sk_xyz789",
  "name": "Production Key 2026",
  "public_key": "ed25519:MC4CAQAwBQYDK2VwBCIEI...",
  "private_key": "ed25519:MFECAQEwBQYDK2VwBCIEI...",
  "created_at": "2026-01-20T10:00:00Z",
  "is_active": true
}

Security Warning: The private key is only returned once when created. Store it securely - we cannot recover it.

GET POST /vendors/domain/ Auth Required

Verify ownership of your domain via DNS TXT record.

# Get verification token
curl https://attestiv.io/api/v1/vendors/domain/token/ \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# Check verification status
curl https://attestiv.io/api/v1/vendors/domain/status/ \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# Trigger verification check
curl -X POST https://attestiv.io/api/v1/vendors/domain/verify/ \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

DNS Setup: Add a TXT record at _attestiv.yourdomain.com with the verification token value.

Invoices

Sign invoices with cryptographic signatures and manage signed documents.

POST /invoices/sign/ Auth Required

Upload and sign an invoice file (PDF, PNG, JPEG, TIFF up to 10MB).

curl -X POST https://attestiv.io/api/v1/invoices/sign/ \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -F "file=@invoice.pdf" \
  -F "key_id=sk_xyz789" \
  -F 'metadata={"invoice_number": "INV-2026-001", "amount": "5000.00", "currency": "USD"}'

Response

{
  "id": "inv_abc123",
  "file_hash": "sha256:a1b2c3d4e5f6...",
  "signature": "ed25519:MEUCIQDx...",
  "signed_at": "2026-01-20T10:30:00Z",
  "key_id": "sk_xyz789",
  "metadata": {
    "invoice_number": "INV-2026-001",
    "amount": "5000.00",
    "currency": "USD"
  },
  "verify_url": "https://attestiv.io/v/inv_abc123"
}
GET /invoices/ Auth Required

List all signed invoices for your account with pagination.

# List invoices (paginated)
curl "https://attestiv.io/api/v1/invoices/?page=1&page_size=20" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# Get specific invoice
curl https://attestiv.io/api/v1/invoices/inv_abc123/ \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Verification

Public endpoints to verify signed invoices. No authentication required - anyone can verify.

POST /verify/invoice/ Public

Upload a file to verify its signature and authenticity.

curl -X POST https://attestiv.io/api/v1/verify/invoice/ \
  -F "file=@invoice.pdf"

Response (Verified)

{
  "verified": true,
  "vendor": {
    "id": "vnd_abc123",
    "name": "Acme Corporation",
    "domain": "acme.com",
    "is_domain_verified": true,
    "verified_since": "2025-06-15"
  },
  "signed_at": "2026-01-20T10:30:00Z",
  "key_status": "valid",
  "metadata": {
    "invoice_number": "INV-2026-001"
  }
}

Response (Not Verified)

{
  "verified": false,
  "reason": "no_signature_found"
}
POST /verify/hash/ Public

Verify using a pre-computed SHA-256 hash (useful for large files or batch verification).

# First compute SHA-256 hash locally
FILE_HASH=$(sha256sum invoice.pdf | cut -d' ' -f1)

# Then verify
curl -X POST https://attestiv.io/api/v1/verify/hash/ \
  -H "Content-Type: application/json" \
  -d "{\"hash\": \"$FILE_HASH\"}"
GET /verify/vendor/{vendor_id}/ Public

Get public information about a verified vendor.

curl https://attestiv.io/api/v1/verify/vendor/vnd_abc123/

Response

{
  "id": "vnd_abc123",
  "name": "Acme Corporation",
  "domain": "acme.com",
  "is_domain_verified": true,
  "verified_since": "2025-06-15",
  "active_keys_count": 2,
  "total_signed_invoices": 1542
}

Customers

Manage customer accounts for receiving and verifying invoices.

POST /customers/register/ Public

Register a new customer account.

curl -X POST https://attestiv.io/api/v1/customers/register/ \
  -H "Content-Type: application/json" \
  -d '{
    "username": "buyer_inc",
    "email": "ap@buyer.com",
    "password": "secure_password_123",
    "name": "Buyer Inc."
  }'
GET /customers/me/ Auth Required

Get your customer profile.

curl https://attestiv.io/api/v1/customers/me/ \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Banking Registry

Zero-knowledge encrypted banking details registry. Data is encrypted client-side before transmission.

POST /banking/details/ Auth Required

Store encrypted banking details. Data must be encrypted client-side using X25519 key exchange.

# Banking details must be encrypted client-side first
curl -X POST https://attestiv.io/api/v1/banking/details/ \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "encrypted_data": "BASE64_ENCRYPTED_PAYLOAD",
    "ephemeral_public_key": "X25519_EPHEMERAL_KEY",
    "nonce": "ENCRYPTION_NONCE"
  }'

Zero-Knowledge: Banking details are encrypted on your device before transmission. Attestiv cannot read or access your banking information.

POST /banking/grants/ Auth Required

Grant a customer access to view your encrypted banking details.

curl -X POST https://attestiv.io/api/v1/banking/grants/ \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "cust_xyz789",
    "expires_at": "2026-12-31T23:59:59Z"
  }'

Error Handling

The API uses standard HTTP status codes and returns errors in a consistent format.

Error Response Format

{
  "error": "error_code",
  "message": "Human-readable error message",
  "details": { /* Optional additional context */ }
}

Common Status Codes

Code Meaning Description
200 OK Request succeeded
201 Created Resource created successfully
400 Bad Request Invalid request parameters
401 Unauthorized Missing or invalid authentication
403 Forbidden Authenticated but not authorized
404 Not Found Resource does not exist
429 Too Many Requests Rate limit exceeded
500 Server Error Something went wrong on our end

Rate Limiting

API requests are limited to 100 requests per minute per API key. Check the X-RateLimit-Remaining header for your current quota.