Custom API Integration
Build custom integrations with any platform using Continuata's REST API for complete control over digital product delivery.
Common Integration Patterns
Order Processing
Generate download tokens when payments are confirmed.
- Payment webhook → API call
- Automatic token generation
- Email delivery integration
Customer Portal
Build download libraries for returning customers.
- Purchase history API
- Download link generation
- Usage analytics display
Basic Workflow
Here's a typical integration workflow for generating download tokens after a purchase:
Customer Completes Purchase
Your payment processor (Stripe, PayPal, etc.) confirms the transaction.
Generate Download Token
Call Continuata API to create a secure download token for the purchased products.
Deliver to Customer
Send the download link via email, add to customer account, or integrate with your platform.
API Endpoints
Generate Download URL
POST /api/generate-download-url
{
"productId": "epic-drums-v1",
"version": "1.0.0"
}
Response:
{
"success": true,
"productId": "epic-drums-v1",
"version": "1.0.0",
"downloadToken": "8b5d…",
"downloadUrl": "https://continuata.io/download?token=8b5d…",
"expiresAt": "2026-04-02T00:00:00.000Z"
}
List Org Purchases
Returns every purchase recorded against your organisation. There is currently no customerEmail filter — filter client-side, or point the customer at continuata.io/my for self-service.
GET /api/purchases
Download Sessions Report (CSV)
GET /api/reports/downloads?from=2026-04-01&to=2026-04-30
Admin-only. Returns CSV. See Downloads API for full parameters.
Example: Node.js Integration
Minimal example showing how to mint a download URL after a payment confirmation:
const express = require('express');
const app = express();
app.use(express.json());
const CONTINUATA_API_KEY = process.env.CONTINUATA_API_KEY;
async function mintDownloadUrl(productId, version) {
const res = await fetch('https://continuata.io/api/generate-download-url', {
method: 'POST',
headers: {
Authorization: `Bearer ${CONTINUATA_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ productId, version })
});
if (!res.ok) throw new Error(`Continuata API ${res.status}: ${await res.text()}`);
return res.json();
}
app.post('/payment-success', async (req, res) => {
const { customerEmail, items } = req.body;
const downloadLinks = [];
for (const item of items) {
if (item.type !== 'digital') continue;
const { downloadUrl, expiresAt } = await mintDownloadUrl(item.productId, item.version);
downloadLinks.push({ product: item.name, downloadUrl, expiresAt });
}
// Send the per-item links *and* a link to https://continuata.io/my so
// the customer can recover access after the 24-hour token expires.
await sendDownloadEmail(customerEmail, downloadLinks);
res.json({ success: true, downloadLinks });
});
app.listen(3000);
Error Handling
Errors return JSON with an error field and an HTTP status. Common cases:
async function safeMintDownloadUrl(productId, version) {
const res = await fetch('https://continuata.io/api/generate-download-url', {
method: 'POST',
headers: { Authorization: `Bearer ${CONTINUATA_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ productId, version })
});
if (res.status === 401) throw new Error('Invalid API key — refresh in Settings → API Key');
if (res.status === 403) throw new Error('Org role too low — generate the key under an admin account');
if (res.status === 404) throw new Error(`No active manifest for ${productId}@${version}`);
if (!res.ok) throw new Error(`Continuata API ${res.status}: ${await res.text()}`);
return res.json();
}
Need Help? Check the Authentication docs for API setup, or contact support@continuata.com for integration assistance.