Publisher API
Verify a buyer's proof of purchase, pull your own sales data, and gift assets — all programmatically. The verify endpoint is field-compatible with Unity's Publisher API, so porting an existing Unity license-gate integration is nearly a base-URL swap.
Authentication
Every request authenticates with a Publisher API key, scoped to a single storefront. A request can only ever read or affect that storefront's data. Pass the key one of two ways:
Recommended — Authorization header
curl https://thedevloot.com/api/publisher/v1/invoices/verify?invoice=DL-2026-000123 \ -H "Authorization: Bearer dlpk_live_xxxxxxxx..."
Unity-compatible — query parameter
For drop-in compatibility with an existing Unity Publisher API integration that sends the key as ?key=:
curl "https://thedevloot.com/api/publisher/v1/invoices/verify?key=dlpk_live_xxxx...&invoice=DL-2026-000123"
The header form is preferred — query-string keys leak into server logs and browser history. Both work identically.
Getting a key
- Open your API dashboard.
- Click Generate key, optionally label it.
- Copy the key — it's shown once and never retrievable again. Store it as a secret.
Keys look like dlpk_live_…. Revoke any key from the same dashboard; revocation is immediate.
Verify invoices
GET /api/publisher/v1/invoices/verify
The proof-of-purchase endpoint. Pass one or more invoice numbers (comma-separated, up to 50). Returns the matching invoices that belong to your storefront. Unknown or other publishers' invoice numbers are silently omitted (never an error, never another publisher's data).
Parameters
invoice— required. One number, or several comma-separated.
Example
GET /api/publisher/v1/invoices/verify?invoice=DL-2026-000123,DL-2026-000124
Authorization: Bearer dlpk_live_xxxx...
200 OK
{
"invoices": [
{
"invoice": "DL-2026-000123",
"package": "GameCatalyst",
"package_id": "prod_1773701493669_dwkt0r",
"date": "2026-05-02",
"refunded": "No",
"quantity": "1",
"price_exvat": "40.00",
"currency": "USD",
"downloaded": "Yes",
"other_license": "No"
}
]
}List / filter invoices
GET /api/publisher/v1/invoices
Returns your invoices, newest first. Use it for your own reporting or to reconcile sales by asset.
Parameters (all optional)
package— filter by asset display name(s), comma-separated, substring match.from,to— date range,YYYY-MM-DD, inclusive.limit— page size, default 50, max 200.cursor— pass backnextCursorfrom the prior response to paginate.
GET /api/publisher/v1/invoices?package=GameCatalyst,StormWeave&from=2026-04-01
Authorization: Bearer dlpk_live_xxxx...
200 OK
{ "invoices": [ /* …same shape as verify… */ ], "nextCursor": "DL-2026-000088" }Sales summary
GET /api/publisher/v1/sales/summary
Monthly roll-up for trend tracking: gross, refunds, net, unit counts, plus a per-package breakdown. Amounts are in minor units (cents) and are not currency-converted — mixed-currency sales stay separable via byCurrency.
GET /api/publisher/v1/sales/summary?from=2026-01-01
Authorization: Bearer dlpk_live_xxxx...
200 OK
{
"totals": { "gross": 128000, "refunds": 4000, "net": 124000, "units": 32 },
"byCurrency": { "USD": 128000 },
"monthly": [
{ "month": "2026-04", "gross": 64000, "refunds": 0, "net": 64000, "units": 16, "refundedCount": 0 }
],
"byPackage": [
{ "package": "GameCatalyst", "gross": 96000, "units": 24, "refundedCount": 1 }
]
}Gifting
POST /api/publisher/v1/gifts
Grant a license for one of your own products to a user, free. The asset lands in their Library and generates a $0.00 invoice you can verify through this same API — which makes gifting a convenient way to test your integration end-to-end.
Body
productId— must be one of your products.recipientEmail— the recipient must already have a DevLoot account.
POST /api/publisher/v1/gifts
Authorization: Bearer dlpk_live_xxxx...
Content-Type: application/json
{ "productId": "prod_1773701493669_dwkt0r", "recipientEmail": "tester@example.com" }
200 OK
{ "success": true, "invoice": "DL-2026-000200", "recipientUid": "…", "remainingThisWindow": 4, "limit": 5 }Quota
Gift volume is metered by DevLoot (it consumes storage + API resources):
- Free — 5 gifts per rolling 30 days.
- Pro — 100 gifts per rolling 30 days.
Check current usage with GET /api/publisher/v1/gifts:
200 OK
{ "tier": "free", "used": 1, "limit": 5, "remaining": 4, "windowDays": 30 }Invoice field reference
The object returned by verify and list:
| Field | Type | Description |
|---|---|---|
| invoice | string | Invoice number, e.g. DL-2026-000123. |
| package | string | Display name of the asset (matches your listing name). |
| package_id | string | Stable product id. |
| date | string | Purchase date, YYYY-MM-DD. |
| refunded | 'Yes' | 'No' | Has the purchase been refunded or charged back? |
| reason | string (optional) | Present only when refunded — 'refund' or 'chargeback'. |
| quantity | string | Number of licenses purchased. |
| price_exvat | string | Line total excluding tax, decimal (Stripe handles VAT at checkout). |
| currency | string | ISO currency of price_exvat (e.g. USD). |
| downloaded | 'Yes' | 'No' | Has the buyer downloaded the asset yet? |
| other_license | 'Yes' | 'No' | Does the buyer hold a separate valid license for this product? |
Errors
| Status | code | Meaning |
|---|---|---|
| 400 | missing_invoice / bad_body | Required parameter or body missing. |
| 402 | pro_required | Endpoint needs DevLoot Pro — upgrade your storefront. |
| 403 | invalid_api_key | No or unknown API key. |
| 403 | not_your_product | Gifting a product that isn’t yours. |
| 404 | recipient_not_found | Gift recipient has no DevLoot account yet. |
| 429 | gift_quota_* / rate_limited | Gift quota hit, or too many requests. |
| 500 | internal | Server error — retry shortly. |
Rate limits
verify— 120 requests / minute.invoices(list) — 60 / minute.sales/summary— 30 / minute.gifts— 20 / minute (plus the 30-day quota above).
Exceeding a limit returns 429. Limits are per-IP.
Migrating from Unity's Publisher API
If you already gate content against Unity's invoice-verify endpoint, the move is mostly mechanical:
- Base URL → swap Unity's verify URL for
https://thedevloot.com/api/publisher/v1/invoices/verify. - Key → use your DevLoot key. Both
?key=andAuthorization: Bearerare accepted. - Response fields are identical (
invoice,package,package_id,refunded,quantity,price_exvat,currency,downloaded,other_license), so your package-name → role mapping works unchanged. - Batch verify works the same — comma-separate invoice numbers in one call.
- Watch out: DevLoot invoice numbers are formatted
DL-2026-000123, not Unity's numeric ids. If your plugin validates invoice numbers with a digits-only regex, loosen it to accept theDL-prefix. - VAT — DevLoot lets Stripe handle tax at checkout, so
price_exvatis simply your pre-tax line price. There's no deprecatedprice_usd_exvatfield.
Questions or a field you need that isn't here? Reach us via Contact. We read every API request.