Back
Developers
API v1

Start building in minutes

Integrate signed document verification into your app with just a few lines of code. No complex setup required.

Simple REST API
JSON responses
Test mode included

Secure Verification

Verify cryptographic signatures and document status in real-time.

Fast Response

Optimized API with millisecond response times.

All Types

Supports single PDF, multi-signature, and wallet certificates.

Connect your wallet

Connect your wallet to create and manage API keys.

Documentation

Single endpoint to verify any type of certificate.

GET/api/v1/verify

Parameters

id
stringrequired

Certificate ID (e.g., PDF-MS-xxx, PDF-xxx, or wallet ID)

Headers

x-api-key
stringrequired

Your ProofLayer API key

Examples

curl -X GET "https://prooflayer.ink/api/v1/verify?id=PDF-MS-1779027938314-COpJ33AX" \
  -H "x-api-key: pl_test_your_api_key"

Example Response

{
  "success": true,
  "data": {
    "valid": true,
    "type": "multisig_pdf",
    "certificate": {
      "id": "PDF-MS-1779027938314-COpJ33AX",
      "filename": "contract.pdf",
      "fileHash": "a03d1e666a2a9a1e4ab68e8f...",
      "status": "completed",
      "requiredSignatures": 2,
      "completedSignatures": 2,
      "isComplete": true,
      "signers": [...]
    },
    "verifyUrl": "https://prooflayer.ink/verificar/PDF-MS-1779027938314-COpJ33AX"
  },
  "meta": {
    "environment": "test",
    "timestamp": "2026-05-17T14:30:00Z"
  }
}
Certificate Types
PDF-MS-*Multi-Signature PDF

PDF documents signed by multiple wallets

PDF-*Single-Signature PDF

PDF documents signed by a single wallet

DOC-*Text Document

Text documents signed by one or more wallets

Creation Endpoints

Create documents programmatically. Users sign in the ProofLayer UI.

POST/api/v1/pdf/multisig/create

Create multi-signature PDF document

Body (multipart/form-data)

filerequired- PDF file
signersrequired- JSON array: [{wallet, name?, organization?, role?}]
requiredSignaturesoptional- Number (defaults to signers.length)
curl -X POST "https://prooflayer.ink/api/v1/pdf/multisig/create" \
  -H "x-api-key: pl_test_xxx" \
  -F "file=@contract.pdf" \
  -F 'signers=[{"wallet":"0x123...","name":"Alice","role":"CEO"},{"wallet":"0x456...","name":"Bob"}]'
POST/api/v1/pdf/create

Create single-signature PDF document

Body (multipart/form-data)

filerequired- PDF file
signerrequired- Wallet address (0x...)
nameoptional - Signer name
organizationoptional - Organization
roleoptional - Role/title
curl -X POST "https://prooflayer.ink/api/v1/pdf/create" \
  -H "x-api-key: pl_test_xxx" \
  -F "file=@contract.pdf" \
  -F "signer=0x7dA443837Bb1df22EE5e2BC5892843401659515D" \
  -F "name=John Doe" \
  -F "organization=Acme Inc"
POST/api/v1/document/create

Create text document for multi-signature

Body (JSON)

{
  "title": "Service Agreement",
  "content": "Terms and conditions...",
  "signers": [
    {"wallet": "0x123...", "name": "Alice", "organization": "Acme Inc", "role": "CEO"},
    {"wallet": "0x456...", "name": "Bob"}
  ]
}

Response

{
  "success": true,
  "data": {
    "id": "DOC-1234567890-AbCdEf",
    "signUrl": "https://prooflayer.ink/firmar/DOC-1234567890-AbCdEf",
    "verifyUrl": "https://prooflayer.ink/verificar/DOC-1234567890-AbCdEf",
    "signers": [...]
  }
}

Transaction Certificate API

Generate verifiable certificates for blockchain transactions. Send a txHash and receive a certificate with PDF and verification URL.

POST/api/v1/transaction-certificate/create

Request body

txHashrequired- Transaction hash (required)
chainId- Chain ID (1=Ethereum, 137=Polygon, etc.)
networkKey- Alternative to chainId: ethereum, polygon, bsc, arbitrum, base, optimism
certificateType- Certificate type: transfer, payment, loan, custom
customMessageoptional - Optional custom message
languageoptional - Language: en or es
curl -X POST "https://prooflayer.ink/api/v1/transaction-certificate/create" \
  -H "x-api-key: pl_test_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "txHash": "0x123abc...",
    "networkKey": "ethereum",
    "certificateType": "transfer"
  }'

Response example

{
  "success": true,
  "data": {
    "certificateId": "TX-CERT-1234567890-AbCd",
    "status": "created",
    "txHash": "0x123abc...",
    "network": "Ethereum",
    "from": "0x...",
    "to": "0x...",
    "amount": "1.5",
    "token": "ETH",
    "usdValue": "3500.00",
    "timestamp": "2026-05-19T12:00:00Z",
    "printableUrl": "https://prooflayer.ink/api/v1/transaction-certificate/TX-CERT.../pdf",
    "verifyUrl": "https://prooflayer.ink/verificar/TX-CERT..."
  }
}

Payment Receipt API

Generate verifiable payment receipts. Ideal for platforms with their own checkout that accept crypto.

POST/api/v1/receipts/payment

Request body

txHashrequired- Transaction hash (required)
chainId / networkKeyrequired- Chain ID (1=Ethereum, 137=Polygon, etc.)
orderIdrequired- Order ID in your system (required)
productNamerequired- Product name (required)
merchantNamerequired- Merchant name (required)
merchantWalletrecommended- Merchant wallet (recommended for validation)
expectedAmountoptional - Expected amount (for validation)
Server-Side Validation

The API validates the transaction directly on the blockchain. Never trust client-provided data.

Replay protection

Duplicate txHash + orderId combinations are detected and return the existing receipt.

curl -X POST "https://prooflayer.ink/api/v1/receipts/payment" \
  -H "x-api-key: pl_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "txHash": "0x456def...",
    "networkKey": "polygon",
    "orderId": "ORDER-12345",
    "productName": "Premium Subscription",
    "merchantName": "Acme Inc",
    "merchantWallet": "0x7dA443837Bb1df22EE5e2BC5892843401659515D",
    "expectedAmount": 50
  }'

Response example

{
  "success": true,
  "data": {
    "receiptId": "RCPT-1234567890-XyZw",
    "status": "created",
    "txHash": "0x456def...",
    "network": "Polygon",
    "payerWallet": "0xcustomer...",
    "merchantWallet": "0x7dA443...",
    "amount": "50.0",
    "token": "USDC",
    "usdValue": "50.00",
    "transferType": "erc20",
    "timestamp": "2026-05-19T12:00:00Z",
    "orderId": "ORDER-12345",
    "productName": "Premium Subscription",
    "merchantName": "Acme Inc",
    "printableReceiptUrl": "https://prooflayer.ink/api/v1/receipts/RCPT.../pdf",
    "verifyUrl": "https://prooflayer.ink/verificar/RCPT..."
  }
}

Invisible Checkout Receipt

Generate verifiable receipts automatically after each crypto payment - no widgets or visible integration.

For platforms that already have their own crypto checkout. ProofLayer does not custody funds - it only verifies transactions and generates receipts.

Integration flow

1
1. User completes payment in your existing checkout
2
2. Your backend receives the transaction txHash
3
3. Your backend calls ProofLayer API with txHash + metadata
4
4. ProofLayer validates the transaction on-chain
5
5. You receive receiptId, printableReceiptUrl and verifyUrl

Receipt Status

pendingpending - Transaction not yet confirmed
verifiedverified - Receipt created and verified
failedfailed - Validation failed (wrong merchantWallet, amount, etc.)
duplicateduplicate - Receipt already exists for this txHash + orderId
ERC20 Validation

For token payments (USDC, USDT, DAI), the API parses Transfer event logs to validate that merchantWallet received the payment.

Error: merchantWallet is not receiver

If the transaction does not send funds to merchantWallet, the API returns error 400 with validationError.

{
  "success": false,
  "data": {
    "status": "failed",
    "error": "Transaction receiver (0xcontract...) does not match merchantWallet (0xmerchant...)",
    "txHash": "0x...",
    "webhookEvent": "receipt.failed"
  },
  "error": "Transaction receiver (0xcontract...) does not match merchantWallet..."
}

JavaScript Example

// After payment is confirmed in your checkout
async function generateReceipt(txHash, orderData) {
  const response = await fetch('https://prooflayer.ink/api/v1/receipts/payment', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': process.env.PROOFLAYER_API_KEY,
    },
    body: JSON.stringify({
      txHash,
      networkKey: 'polygon', // or chainId: 137
      orderId: orderData.id,
      productName: orderData.productName,
      merchantName: 'Your Company',
      merchantWallet: process.env.MERCHANT_WALLET,
      expectedAmount: orderData.amount, // optional validation
      expectedToken: 'USDC', // optional validation
    }),
  });
  
  const { data, error } = await response.json();
  
  if (data.status === 'verified') {
    // Success! Save receipt URL
    await saveReceiptToOrder(orderData.id, {
      receiptId: data.receiptId,
      printableReceiptUrl: data.printableReceiptUrl,
      verifyUrl: data.verifyUrl,
    });
  } else if (data.status === 'pending') {
    // Transaction not confirmed yet - retry later
    scheduleRetry(txHash, orderData);
  } else if (data.status === 'duplicate') {
    // Receipt already exists - use existing
    return data;
  }
  
  return data;
}
Idempotency Note

Repeated calls with the same txHash + orderId return the existing receipt with status: duplicate.

Internal ProofLayer Use Case

This same API is used internally to generate receipts for PRO/Enterprise payments.

After-Payment Widget

Display verifiable receipts automatically after each crypto payment.

For merchants who already have their own crypto checkout. Embed the widget on your success/thank-you page.

When to use

After the user completes a payment in your existing checkout and you have the txHash.

How it works

1
1. User completes payment in your checkout
2
2. Your backend gets the txHash
3
3. You pass the txHash to the widget via data attributes
4
4. Widget verifies and displays the receipt

Embed code

<!-- Include the widget script -->
<script src="https://prooflayer.ink/embed/receipt-widget.js"></script>

<!-- Widget container -->
<div
  data-prooflayer-widget="receipt"
  data-public-key="pk_widget_test_your_public_key"
  data-tx-hash="0x..."
  data-network-key="polygon"
  data-order-id="ORDER-123"
  data-product-name="Annual Subscription"
  data-merchant-name="Your Company"
  data-merchant-wallet="0x..."
  data-customer-name="John Doe"
  data-theme="light"
  data-language="en"
></div>

Supported attributes

data-public-keyrequired- Your widget public key pk_widget_... (required)
data-tx-hashrequired- Transaction hash (required)
data-network-key- Network: ethereum, polygon, base, etc.
data-order-id- Order ID in your system
data-product-name- Product name
data-merchant-name- Merchant name
data-merchant-walletrecommended- Merchant wallet (for validation)
data-customer-name- Customer name (optional)
data-theme- Theme: light or dark
data-language- Language: en or es

Widget states

Verifying - Querying blockchain
Verified - Receipt created successfully
Pending - Transaction not yet confirmed
Failed - Validation error
Security model
  • Widget uses public keys (pk_widget_*), NOT secret keys
  • Domain restrictions configurable per key
  • All tx validation is done server-side
  • Secret keys (pl_*) for backend-to-backend only

API Key Types

Secret Key (pl_live_*, pl_test_*)

For backend-to-backend use only. NEVER expose in frontend.

pl_live_abc123... (backend only)
Widget Public Key (pk_widget_live_*, pk_widget_test_*)

Safe to use in embedded widgets. Configure allowed domains.

pk_widget_live_xyz789... (frontend safe)
Domain restrictions

Widget public keys can be restricted to specific domains. In test mode, localhost is allowed by default.

Rate Limits
60
Requests per minute
5
Maximum API keys

Need help? Contact support@prooflayer.ink