Programmatic access to your ProofNudge account. Manage projects, testimonials, widgets, video uploads, and analytics via REST API.
All API requests require authentication via an API key. API access is available exclusively on the Scale plan.
Include your key in the Authorization header of every request:
curl -H "Authorization: Bearer pn_live_a3f8b2c1d4e5f6..." \ https://app.proofnudge.com/api/projects
Keep your API key secret. Never expose it in client-side code, public repositories, or browser requests. If compromised, revoke it immediately from Settings and generate a new one.
API requests are rate-limited per user using a sliding window. When you exceed the limit, you'll receive a 429 response.
| Tier | Limit | Window |
|---|---|---|
| write | 30 requests | 60 seconds |
| read | 60 requests | 60 seconds |
| ai | 5 requests | 60 seconds |
Every response includes:
X-RateLimit-Limit: 30 X-RateLimit-Remaining: 28 X-RateLimit-Reset: 1719835260 Retry-After: 45 # (only on 429 responses)
All errors return a JSON object with an error field. Some include additional context.
| Status | Meaning |
|---|---|
| 400 | Bad Request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not Found |
| 429 | Too Many Requests |
| 500 | Internal Error |
{
"error": "Testimonial limit reached",
"message": "Your current plan allows 10 testimonials. Upgrade to Pro for unlimited.",
"upgradeUrl": "/dashboard/billing"
}When configured, ProofNudge sends POST requests to your webhook URL for widget events. Each request is signed with HMAC SHA-256.
const crypto = require('crypto');
function verifyWebhook(body, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return signature === `sha256=${expected}`;
}
// In your handler:
const sig = req.headers['x-proofnudge-signature'];
const isValid = verifyWebhook(rawBody, sig, webhookSecret);{
"event": "event.conversion",
"data": {
"id": "evt_abc123",
"type": "CONVERSION",
"widgetId": "wdg_xyz",
"widgetName": "Pricing Carousel",
"referrer": "https://example.com/pricing"
},
"timestamp": "2026-07-01T10:30:00.000Z",
"projectId": "prj_456"
}| Event Type | Trigger |
|---|---|
| event.view | Widget rendered on a page |
| event.click | User clicked on a testimonial or CTA |
| event.conversion | User clicked the CTA link (conversion tracked) |
A minimal example using fetch to list testimonials and create a new one:
const API_KEY = "pn_live_YOUR_KEY";
const BASE = "https://app.proofnudge.com";
const headers = {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json",
};
// List testimonials
const testimonials = await fetch(
`${BASE}/api/testimonials?projectId=prj_abc123`,
{ headers }
).then(r => r.json());
console.log(`Found ${testimonials.length} testimonials`);
// Create a testimonial
const newTestimonial = await fetch(`${BASE}/api/testimonials`, {
method: "POST",
headers,
body: JSON.stringify({
projectId: "prj_abc123",
content: "Absolutely love this product!",
author: "Alex M.",
rating: 5,
}),
}).then(r => r.json());
console.log(`Created: ${newTestimonial.id}`);
// Approve a pending review
await fetch(`${BASE}/api/testimonials/${newTestimonial.id}/status`, {
method: "PUT",
headers,
body: JSON.stringify({ status: "approved" }),
});