Skip to main content
Version: v2

Survey campaign API

The advertiser survey API is mounted at /api/v1/campaigns. It is intended for approved advertiser accounts integrating from their server. Dashboard users can follow the survey campaign workflow without calling these endpoints.

Authentication​

Send your advertiser X-Api-Key over HTTPS. Requests also require a URL signature in the enc query parameter, derived from the advertiser secret and request body. The service rejects missing keys, unknown keys, pending advertiser accounts, and invalid signatures. Keep the key and secret on your server and validate the exact signing output with your RapidoReach integration contact before connecting traffic. Do not reuse a publisher application API key.

The current signing implementation hashes the full request URL without a query string, then the JSON serialization of a nonempty body, then the advertiser secret. It appends the hex digest as the sole ?enc=... query value. The request scheme and host must match what the server reconstructs from its forwarded protocol and Host header. Body serialization must match what the server receives. The account's configured url_security_encryption_type selects SHA-1, SHA-256, or SHA3-256; the helper falls back to SHA3-256 for an unrecognized value. Confirm your account's configured algorithm before using the sample below. Test signing in development before automating a write; do not add other query parameters to a signed URL.

For a current SHA3-256 account, a server can construct a request as follows. Confirm the algorithm and base URL for your account before use; this sample makes no network request.

const { createHash } = require('node:crypto');
const baseUrl = 'https://YOUR_DEVELOPMENT_HOST/api/v1/campaigns/create';
const body = {
name: 'Example study', country_language_id: 'YOUR_MARKET_ID',
cpi: 1.5, length_of_interview: 10, conversion: 20,
start_date: '2026-10-01', end_date: '2026-10-15',
survey_live_link: 'https://survey.example/live?transaction={transaction_id}',
survey_test_link: 'https://survey.example/test?transaction={transaction_id}',
max_daily_completes: 50,
};
const json = JSON.stringify(body);
const digest = createHash('sha3-256')
.update(baseUrl + json + process.env.RAPIDOREACH_ADVERTISER_SECRET)
.digest('hex');
const signedUrl = `${baseUrl}?enc=${digest}`;
// Send json as the POST body and X-Api-Key from protected server configuration.

Both survey links must contain the exact {transaction_id} macro. Preserve its resolved value throughout the survey and result redirects. Confirm accepted link formats with the dashboard and a development request.

Campaign endpoints​

MethodPathPurpose
GET/getcampaignsList campaigns visible to the authenticated creator
POST/searchcampaignsSearch campaigns
POST/createCreate a draft campaign
GET/:campaignIdRead a campaign
PUT/:campaignIdUpdate a campaign, subject to route policy
POST/clonecampaignsClone a campaign for a new study
DELETE/:campaignIdDelete a campaign where policy allows

Create and update validate the live and test survey link templates. A name on create must be at least four characters. Keep the live and test URLs separate and verify redirects before funding. Treat campaign IDs as opaque, and keep each advertiser's IDs and credentials separate. Do not use an ID alone as your own authorization check.

Create request fields​

POST /create accepts a JSON body with the project fields below. Values must match the same market, pricing, and link assumptions used in the dashboard.

FieldPurpose
nameInternal campaign name, at least four characters
country_language_idTarget country and language identifier
cpiCost per completed interview
length_of_interviewExpected minutes per interview
conversionExpected completion percentage
start_date, end_dateField dates
survey_live_link, survey_test_linkValidated live and test survey link templates
max_daily_completesDaily completion limit
supported_devicesDevice eligibility list
research_category, research_industry, campaign_manager, tagsOptional project metadata

On success, create returns HTTP 201 with campaign and creator objects; the creator response includes a test_redirect_url. Use that test URL to check outcomes before funding. Invalid input or signing prevents creation. Treat response IDs and test URLs as opaque; do not build new URLs from their internal structure.

{
"message": "Campaign created successfully",
"campaign": {"_id": "CAMPAIGN_ID", "name": "Example study"},
"creator": {"_id": "ADVERTISER_USER_ID", "test_redirect_url": "/test/survey/..."}
}

Quotas and screening​

MethodPathPurpose
GET/:campaignId/getcampaignquotaList campaign quotas
POST/:campaignId/campaignsquotaCreate a quota
GET / PUT / DELETE/:campaignId/campaignsquota/:campaignQuotaIdRead, update, or remove a quota
GET/:campaignId/getcustomquestionsList custom screeners
POST/:campaignId/customquestionCreate a screener
GET / PUT / DELETE/:campaignId/customquestion/:customquestionIdRead, update, or remove a screener
POST/:campaignId/clonecampaignsquotaClone a campaign quota
GET/:campaignId/campaignsquota/:campaignQuotaId/getcampaignsqualificationsList qualifications
POST/:campaignId/campaignsquota/:campaignQuotaId/campaignsqualificationAdd a qualification
GET / PUT / DELETE/:campaignId/campaignsquota/:campaignQuotaId/campaignsqualification/:campaignQualificationsIdRead, update, or remove a qualification
POST/cq/:customquestionId/createoptionAdd a screener answer option
PUT / DELETE/cq/:customquestionId/option/:option_idUpdate or remove an answer option

POST /:campaignId/campaignsquota accepts name and num_respondents in JSON and returns 201 with campaignQuota. POST /:campaignId/clonecampaignsquota takes {"quotaId":"SOURCE_QUOTA_ID"}. A new custom question and a new answer option are initialized with defaults; update the returned IDs with the question and answer text and acceptance rules before using them to screen respondents. Read the saved quota and question back before assigning supply or funding.

Additional endpoints: POST /listcountrylanguage lists supported markets; POST /getProfilingQuestionsForTargeting returns profiling catalog data; GET /:campaignId/getcustomquestionsforprofiling returns campaign screeners for profiling; GET /downloadresponses downloads responses; GET /invoices lists invoices. These depend on campaign state and account configuration. Start with reads in development, then test a complete draft, quota, screener, redirect, and funding flow before API writes. API creation alone does not activate or fund a campaign. See survey API errors and checks.