Quickstart
Two minutes from zero to your first API call:
- In the panel, open API Keys in the sidebar and click + New key. Give it a name and a scope.
- Copy the key — it's shown exactly once. We store only its hash, so it can't be recovered later.
- Send it as a Bearer token:
curl https://app.vouchdock.com/v1/sites \
-H "Authorization: Bearer vd_live_your_key_here"
That's the whole setup. No OAuth dance, no refresh tokens, no sandbox environment — the same production API the panel uses.
Authentication
All endpoints live under https://app.vouchdock.com/v1/ and expect a tenant API key in the Authorization header:
Authorization: Bearer vd_live_...
Scopes
| Scope | What it can do |
|---|---|
read | GET endpoints only — content export, stats, link health. Mutations return 403. |
write | Full content management: sites, categories, offers, reviews, articles, media, monetization. Team and API-key management stay login-only, so a leaked key can't lock you out or mint more keys. |
Revoking a key in the panel kills it instantly — the very next request gets a 401.
Login sessions
For interactive flows (your own UI on top, or owner-level actions like key management) there's also POST /auth/login with email + password, returning a short-lived JWT used the same way; POST /auth/resend-verification re-sends the verification email. API keys are the right choice for automation; JWT is for sessions.
Conventions
- JSON in, JSON out. Send
Content-Type: application/jsonon POST/PATCH. Media upload is the onemultipart/form-dataexception. - IDs are UUIDs. Path parameters like
:id,:oid,:cidtake UUIDs returned by list/create calls. - Site scoping. Content belongs to a site: list via
/sites/:id/…, then address items directly (/offers/:oid). - Changes go live in ~5 seconds. The public renderer caches settings briefly; edits appear on your domains within seconds, no deploy.
- Full-update semantics on PATCH. Updates replace the stored record — omitted optional fields are cleared. Read first, modify, send back.
- Plan gating. Some groups (link health, cloaking, postbacks, comparison tables, media library, lead generation (contacts), audit log) depend on your plan; a gated endpoint returns
403naming the missing feature. Check Account & team.
Errors
| Status | Meaning |
|---|---|
400 | Invalid payload — missing or malformed fields. |
401 | Missing, invalid or revoked API key. |
403 | Key scope too narrow (read key attempting a write), or the feature isn't in your plan. |
404 | Not found, or belongs to another tenant (we don't confirm existence across tenants). |
409 | Conflict — e.g. a slug already taken within the site. |
500 | Our side. If it persists, open a ticket from the panel. |
Reference sections
The full field-by-field reference, split by resource. Every create/update payload documented with types, defaults and examples.
Offers & galleries →
The complete offer payload: pros & cons, editorial ratings, SEO fields, info sections, link slots, availability — plus image galleries with uploads and hotlinks.
Reviews & moderation →
Consumer reviews, approval workflow, bulk moderation, operator and visitor replies.
Sites & settings →
Site CRUD plus the full settings object: all 19 appearance options, texts, review config, lead form, JavaScript injection.
Articles, pages & authors →
Blog posts with SEO fields and focus keywords, static pages, author profiles, comment moderation.
Media library →
Uploads, URL imports and automated screenshots — the async job flow included.
Monetization →
Link cloaks, outbound postbacks with macros, tracking pixels, comparison tables, search-query pages.
Landers →
Standalone campaign landing pages: designs, color maps, offer selection, publishing.
Stats & leads →
Click analytics (overview, per-offer, daily, raw log) and captured leads.
Account & team →
Profile, team members and roles, API keys, support tickets, plan details, audit log.
Full workflow example
From empty account to a ranked offer with a review, in five calls:
API=https://app.vouchdock.com/v1
KEY=vd_live_your_key_here
# 1. your sites
SITE=$(curl -s $API/sites -H "Authorization: Bearer $KEY" \
| python3 -c "import json,sys; print(json.load(sys.stdin)['sites'][0]['id'])")
# 2. a category
CAT=$(curl -s -X POST $API/sites/$SITE/categories \
-H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
-d '{"name":"VPN Services","slug":"vpn-services"}' \
| python3 -c "import json,sys; print(json.load(sys.stdin)['id'])")
# 3. an offer in it
OFFER=$(curl -s -X POST $API/sites/$SITE/offers \
-H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
-d "{\"name\":\"Acme VPN\",\"slug\":\"acme-vpn\",\"category_ids\":[\"$CAT\"],\"url\":\"https://acmevpn.example.com\",\"rank\":1,\"status\":\"active\",\"link_slots\":[\"toplink\"]}" \
| python3 -c "import json,sys; print(json.load(sys.stdin)['id'])")
# 4. a consumer review on it
curl -s -X POST $API/reviews \
-H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
-d "{\"offer_id\":\"$OFFER\",\"site_id\":\"$SITE\",\"title\":\"Solid for the price\",\"content\":\"Been using it six months…\",\"rating\":5,\"author_name\":\"Mike T.\",\"status\":\"approved\"}"
# 5. watch it appear — public pages reflect changes within seconds
curl -s https://your-site-domain.com/ | grep -o "Acme VPN"
Build on it
Bulk-import a portfolio of sites, sync offers from your own database, wire moderation into Slack, auto-publish articles from your AI pipeline — if the panel can do it, so can your code.