Factory402 API Docs (Overview)

How to authenticate, pay, and call Factory402 endpoints programmatically.

Base URL

https://api.factory402.com

All endpoints are relative to this base URL. HTTPS is required.

Authentication — x402 Payment Layer

Factory402 uses the x402 protocol for machine-to-machine payment authentication. There are no API keys or OAuth tokens. Each paid request carries its own cryptographic payment proof.

Request Flow

  1. Send a request to any paid endpoint without payment headers.
  2. Receive a 402 Payment Required response containing the price, a unique nonce, and an expiry timestamp.
  3. Construct a payment payload, sign it with your private key, and resend the request with three x402 headers.
  4. If valid, receive a 200 OK response with the intelligence data.

Required Headers

Replay Protection

Each nonce can only be used once. Reuse returns 402 with reason "Nonce already used (replay)". Nonces expire after 5 minutes.

Quickstart Examples

cURL

# Step 1: Get the price (no payment)
curl https://api.factory402.com/api/osint/risk-score
# Returns 402 with nonce, amount, expiry

# Step 2: Build and sign payment (bash)
PAYLOAD='{"asset":"USD","amount":8,"operator":"factory-payment-operator-v1","nonce":"NONCE","expires":"TIMESTAMP","endpoint_id":"osint.risk_score.v1"}'
PAYLOAD_B64=$(echo -n "$PAYLOAD" | base64)
SIGNATURE=$(echo -n "$PAYLOAD_B64" | openssl dgst -sha256 -sign key.pem | base64)
PUBKEY_B64=$(cat pub.pem | base64 -w0)

# Step 3: Paid request
curl -H "x402-payload: $PAYLOAD_B64" \
     -H "x402-signature: $SIGNATURE" \
     -H "x402-public-key: $PUBKEY_B64" \
     https://api.factory402.com/api/osint/risk-score

Python

import base64, json, hashlib, time, requests
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey

private_key = Ed25519PrivateKey.generate()
public_key = private_key.public_key()

payload = {
    "asset": "USD", "amount": 8,
    "operator": "factory-payment-operator-v1",
    "nonce": hashlib.sha256(str(time.time()).encode()).hexdigest()[:16],
    "expires": str(int(time.time()) + 300),
    "endpoint_id": "osint.risk_score.v1",
}
payload_b64 = base64.b64encode(json.dumps(payload).encode()).decode()
sig_b64 = base64.b64encode(private_key.sign(payload_b64.encode())).decode()

resp = requests.get("https://api.factory402.com/api/osint/risk-score", headers={
    "x402-payload": payload_b64,
    "x402-signature": sig_b64,
    "x402-public-key": base64.b64encode(public_key.public_bytes(
        __import__("cryptography.hazmat.primitives.serialization", fromlist=["Encoding"]).Encoding.Raw,
        __import__("cryptography.hazmat.primitives.serialization", fromlist=["PublicFormat"]).PublicFormat.Raw,
    )).decode(),
})
print(resp.json())

JavaScript

const keyPair = await crypto.subtle.generateKey({name:"Ed25519"}, true, ["sign","verify"]);
const payload = {asset:"USD",amount:8,operator:"factory-payment-operator-v1",
  nonce:crypto.randomUUID().replace(/-/g,"").slice(0,16),
  expires:String(Math.floor(Date.now()/1000)+300),endpoint_id:"osint.risk_score.v1"};
const payloadB64 = btoa(JSON.stringify(payload));
const sig = await crypto.subtle.sign("Ed25519",keyPair.privateKey,new TextEncoder().encode(payloadB64));
const res = await fetch("https://api.factory402.com/api/osint/risk-score",{headers:{
  "x402-payload":payloadB64,"x402-signature":btoa(String.fromCharCode(...new Uint8Array(sig))),
  "x402-public-key":btoa(String.fromCharCode(...new Uint8Array(await crypto.subtle.exportKey("raw",keyPair.publicKey))))
}});
console.log(await res.json());

Response Envelope

{"status":200,"endpoint_id":"osint.risk_score.v1","request_id":"uuid","data":{...},"meta":{"processing_ms":"142","room":null,"version":"v1"}}