TrustDeal API
Protected deals between two people, with automatic verification. Integrate in minutes.
What TrustDeal does
TrustDeal turns an informal agreement between two people — over chat, a marketplace, or email — into a protected deal. The buyer locks funds. The seller delivers. TrustDeal verifies the delivery against the agreed terms. If it matches, funds release to the seller. If it doesn't, the buyer gets a refund. No manual dispute process.
You can use TrustDeal's API to power protected transactions inside your marketplace or product.
Quickstart
Create a deal with two API calls. One to create it, one to check its status.
curl -X POST https://trustdealapp.com/api/v1/deals \
-H "Authorization: Bearer td_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"product": "Logo design — PNG + SVG",
"price": "$150",
"delivery_time": "3 days",
"buyer_email": "buyer@example.com",
"seller_email": "seller@example.com"
}'
You'll get back a deal_id and an invite_url. Send the URL to both participants. They complete the flow on TrustDeal, and you get webhook events as the state changes.
Authentication
All API requests require an API key in the Authorization header:
Authorization: Bearer td_live_YOUR_KEY
Keys have two prefixes:
td_live_— production keys. Real money.td_test_— sandbox keys. No real money, no external side effects.
Errors
All errors return JSON in the shape { "error": "human-readable message" }. Use the HTTP status to decide what to do.
| Status | Meaning | What to do |
|---|---|---|
| 400 | Bad request | Check your payload |
| 401 | Missing or invalid key | Check your Authorization header |
| 403 | Forbidden | Key missing the needed permission |
| 404 | Not found | Check the ID |
| 429 | Rate limited | Wait and retry. Respect Retry-After. |
| 500+ | Server error | Retry with exponential backoff. If it persists, contact support with the X-Trace-Id from your response. |
POST/api/v1/deals
Creates a new protected deal.
Request body
| Field | Type | Description |
|---|---|---|
product | string | What's being traded |
price | string | e.g. "$150", "€30" |
delivery_time | string | e.g. "3 days", "1 week". Optional. |
buyer_email | string | Email of the buyer. Optional. |
seller_email | string | Email of the seller. Optional. |
Response 201
{
"deal_id": "9f...",
"invite_url": "https://trustdealapp.com/chat/9f...",
"product": "Logo design — PNG + SVG",
"price": "$150",
"delivery_time": "3 days",
"status": "awaiting_approval",
"created_at": "2026-04-19T12:34:56.789Z"
}
GET/api/v1/deals/:id
Returns current deal status and any verification results.
Response fields
| Field | Description |
|---|---|
status | One of awaiting_approval, awaiting_payment, funds_locked, delivery_submitted, pending_review, completed, refunded, expired |
verification | Present once checks have run. Contains passed, total, and per-check checks array. |
Webhooks
Webhooks are the best way to keep your system in sync with deal state. When a deal changes state, we POST a JSON event to your registered URL.
Event types
| Event | When it fires |
|---|---|
deal.funds_locked | Buyer paid; funds are held securely |
deal.delivery_submitted | Seller submitted a file or link |
deal.pending_review | AI verification match < 50%; buyer will review |
deal.completed | Delivery verified; funds released to seller |
deal.refunded | Delivery didn't match terms; funds returned to buyer |
You can subscribe to specific events, or use a wildcard like deal.* or *.
Subscribe
curl -X POST https://trustdealapp.com/api/v1/webhooks \
-H "Authorization: Bearer td_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/trustdeal",
"events": ["deal.*"],
"description": "Production handler"
}'
The response includes a signing_secret. Store it securely. You'll need it to verify that incoming webhooks actually came from us.
Request shape
We POST JSON to your URL with these headers:
Content-Type: application/json
X-TrustDeal-Event: deal.completed
X-TrustDeal-Id: evt_abc123 (unique — use for dedup)
X-TrustDeal-Signature: sha256=ae...
X-TrustDeal-Timestamp: 1734554321
Body:
{
"id": "evt_abc123",
"type": "deal.completed",
"createdAt": "2026-04-19T12:34:56.789Z",
"data": { "dealId": "...", "amount": "$150" }
}
Verify signatures
Before trusting a webhook, verify its signature. The signature is HMAC-SHA256 over the string {timestamp}.{raw-body}, using your signing secret.
// Node.js
const crypto = require("crypto");
function verify(req, secret) {
const timestamp = req.headers["x-trustdeal-timestamp"];
const signature = req.headers["x-trustdeal-signature"];
const rawBody = req.rawBody; // capture before JSON.parse
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected = crypto.createHmac("sha256", secret)
.update(timestamp + "." + rawBody)
.digest("hex");
const provided = signature.replace("sha256=", "");
return crypto.timingSafeEqual(
Buffer.from(expected, "hex"),
Buffer.from(provided, "hex")
);
}
Delivery guarantees
We retry failed deliveries on this schedule: 1 min, 5 min, 30 min, 2 h, 6 h, 24 h. If all six attempts fail, the event is marked exhausted. You can replay any delivery from the dashboard.
2xx status within 10 seconds. If your handler is slow, queue the work and respond immediately.
GET/api/v1/trust/:email
Returns a user's trust score and badge level. Public endpoint — no API key required.
{
"email": "user@example.com",
"score": 450,
"badge": "gold",
"total_deals": 42,
"completed_deals": 40,
"member_since": "2025-11-03T00:00:00Z"
}
GET/api/v1/stats
Total and completed deals across the platform. Public endpoint.
Need help? support@trustdealapp.com