Consent forwarding
Forward every consent record to your HTTPS endpoint. Use bearer authentication to protect your API.
Consent forwarding sends every saved consent record from OptinStack to an HTTPS endpoint you control. Use it for:
- A customer-owned long-term archive (beyond OptinStack's standard 12-month retention)
- Warehouse ingestion, custom reporting, or internal audit pipelines
- A self-serve operational copy independent of fair-use allowances
OptinStack still stores each record normally. Forwarding runs in the background so a slow or failing endpoint never blocks the live Consent banner.
Authenticated forwarding is recommended
Your endpoint receives consent choices and related identifiers. Prefer Bearer token authentication so only OptinStack (with your secret) can write to that API. No auth is available for quick tests, but unauthenticated public endpoints can be abused and are not recommended for production.
Quick setup
- Create a secure token (see below).
- Build an HTTPS receiver that verifies
Authorization: Bearer <token>. - In the dashboard: Settings → Consent → Records & archive.
- Enable Consent forwarding, enter the HTTPS URL, choose Bearer token, paste the token, then Save.
- Click Test endpoint to send a synthetic consent event and confirm a 2xx response.
Bearer tokens are write-only in OptinStack. After save, the dashboard only shows that a token is configured (not the secret). To rotate, paste a new token and save again.
Generate a secure token
Generate a secure shared secret using a cryptographically secure random generator. The secret should contain at least 32 random bytes. Store it only in your server environment and OptinStack settings—never in client-side code or git.
Examples:
OpenSSL (recommended):
openssl rand -base64 32Node.js:
node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))"Python:
python3 -c "import secrets; print(secrets.token_urlsafe(32))"Example workflow:
# 1. Generate at least 32 random bytes (encoded for pasting)
TOKEN=$(openssl rand -base64 32)
echo "$TOKEN" # paste into OptinStack Settings once
# 2. Store on your receiver (never commit)
export OPTINSTACK_FORWARDING_TOKEN="$TOKEN"Request format
OptinStack sends POST with JSON.
POST /api/optinstack/consents HTTP/1.1
Host: your-api.example.com
Content-Type: application/json
User-Agent: OptinStack-Consent-Forwarder/1.0
X-OptinStack-Project-Id: proj_123
X-OptinStack-Consent-Id: consent_123
Authorization: Bearer YOUR_TOKEN| Header | Purpose |
|---|---|
Authorization | Present when you selected Bearer token. Format: Bearer <token>. |
X-OptinStack-Project-Id | Project that produced the consent. |
X-OptinStack-Consent-Id | Consent record identifier. |
User-Agent | Always OptinStack-Consent-Forwarder/1.0. |
The JSON body is the consent record, including flat category booleans such as analytics, marketing, and preferences (see product consent sync shape). Design your handler to accept additional fields over time.
Verify the bearer token (example)
Always compare against a server-side secret. Reject missing or wrong tokens with 401.
import express from 'express';
const app = express();
app.use(express.json({ limit: '256kb' }));
app.post('/api/optinstack/consents', (req, res) => {
const expected = process.env.OPTINSTACK_FORWARDING_TOKEN;
const auth = req.header('authorization') ?? '';
if (!expected || auth !== `Bearer ${expected}`) {
return res.status(401).json({ error: 'Unauthorized' });
}
const projectId = req.header('x-optinstack-project-id');
const consentId = req.header('x-optinstack-consent-id');
// Persist, enqueue, or warehouse-write here
console.log('OptinStack consent', {
projectId,
consentId,
action: req.body.action,
analytics: req.body.analytics,
marketing: req.body.marketing,
preferences: req.body.preferences,
});
// Prefer 2xx so OptinStack marks delivery successful
return res.status(204).send();
});
app.listen(3000);Checklist for production
- HTTPS only (OptinStack requires a secure endpoint URL)
- Bearer token enabled in OptinStack (not “No auth”)
- Token generated with a CSPRNG (at least 32 random bytes; not a short password)
- Token stored only in secrets manager / env on your receiver
- Endpoint rejects requests without a valid
Authorizationheader - Test endpoint succeeds from Settings after deploy
- You monitor failures (Settings shows last failure reason when delivery fails)
Delivery behavior
- Project-level forwarding (Settings) is preferred. Older request-level
custom_endpointforwarding remains a fallback when no project endpoint is set. - Non-2xx responses or network errors are recorded on the project (last failure reason). Consent ingest still succeeds for the visitor.
- Re-test after fixing your API; OptinStack does not re-send historical records automatically.
Related
- Consent record retention — what OptinStack keeps for 12 months
- Fair-use and Enterprise — traffic allowances and custom volume
Was this helpful?