Traffic2Leads Partner API

Programmatically create and manage Traffic2Leads client accounts — visitor identification, lead caps, and lead delivery, provisioned in a single API call.

Base URL https://partners.traffic2leads.ai

Overview

The Partner API lets approved Traffic2Leads partners provision client accounts under their own management. One POST /v1/accounts call creates the client account, its lead campaign, and its tracking pixel — with a monthly lead cap you control and, optionally, a webhook that delivers every identified lead straight to your systems.

  • Scoped to you. Your API key sees and manages only the accounts you created — nothing else.
  • Setup, not lead routing. Leads flow directly from the Traffic2Leads platform to each account's configured delivery (your webhook, or the account portal). The Partner API is the control plane.
  • Billed from creation. Every account goes live on billing immediately — there is no trial mode. A monthly_lead_cap is required on every account, so spend is always bounded.

Authentication

Every request (except /healthz) requires your partner API key as a Bearer token:

Authorization: Bearer t2l_pk_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Your key was issued to you by the Traffic2Leads team. Keep it server-side — never embed it in a browser or mobile app. If a key is compromised, contact us and we'll rotate it immediately.

Quickstart

Create a fully provisioned client account — pixel, caps, and webhook delivery — in one call:

curl -X POST https://partners.traffic2leads.ai/v1/accounts \
  -H "Authorization: Bearer t2l_pk_XXXX..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: acme-2026-08-07-001" \
  -d '{
    "client_name": "Acme Roofing",
    "client_email": "owner@acmeroofing.com",
    "account_type": "B2C",
    "monthly_lead_cap": 500,
    "webhook_url": "https://your-platform.com/hooks/t2l-leads"
  }'
const res = await fetch('https://partners.traffic2leads.ai/v1/accounts', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer t2l_pk_XXXX...',
    'Content-Type': 'application/json',
    'Idempotency-Key': 'acme-2026-08-07-001',
  },
  body: JSON.stringify({
    client_name: 'Acme Roofing',
    client_email: 'owner@acmeroofing.com',
    account_type: 'B2C',
    monthly_lead_cap: 500,
    webhook_url: 'https://your-platform.com/hooks/t2l-leads',
  }),
});
const account = await res.json();
// SAVE account.portal_password NOW — it is returned exactly once.

Then place the returned pixel_code (or javascript_code) on the client's website, and identified visitors start arriving at your webhook. That's the whole integration.

⚠ The portal password is returned exactly once The create response contains portal_password — the client's login for https://login.traffic2leads.ai. It is not stored and cannot be retrieved again (it is only replayed within the 24-hour idempotency window). Capture it at creation time and deliver it to your client securely.
POST/v1/accounts

Create a client account

Creates the account, its lead campaign (active immediately), and its tracking pixel. Returns everything you need to onboard the client.

Request fields

FieldTypeDescription
client_namestringREQUIREDYour client's business name. A partner prefix is applied automatically to the account name.
client_emailstringREQUIREDThe client's login email. Must not already exist on the platform — you'll get 409 duplicate_email if you've used it before.
account_typestringREQUIRED"B2C" or "B2B" — the kind of lead identification.
monthly_lead_capintegerREQUIREDMax leads per month. Delivery stops at the cap and resumes on the reset day.
daily_capintegerMax leads per day.
cap_reset_dayintegerDay of month (1–28) the monthly cap resets.
delivery_scheduleintegerLead delivery frequency: 1=daily, 2=hourly, 3=every 30 min, 4=every 15 min, 5=every 5 min (default).
state_filtersstring[]Geo filter by US state, e.g. ["TX","OK"]. Mutually exclusive with zip_filters.
zip_filtersstring[]Geo filter by 5-digit ZIP. Mutually exclusive with state_filters.
webhook_urlstringHTTPS endpoint that receives every identified lead. See Webhook lead payload.
validate_onlybooleanDry run: validates everything (including the duplicate-email check) and returns a preview — creates nothing and bills nothing. Use it while building your integration.

Idempotency (recommended)

Send an Idempotency-Key header (any unique string, up to 128 chars) with every create. If your request times out and you retry with the same key within 24 hours, you get the original response back (marked with an Idempotency-Replayed: true header) instead of a second billed account.

Response 201

{
  "account_id": 42,
  "client_name": "SG — Acme Roofing",
  "client_email": "owner@acmeroofing.com",
  "account_type": "B2C",
  "caps": { "monthly_lead_cap": 500, "daily_cap": null, "cap_reset_day": null },
  "delivery_schedule": null,
  "state_filters": null,
  "zip_filters": null,
  "status": "active",
  "webhook_url": "https://your-platform.com/hooks/t2l-leads",
  "pixel_code": "<img src='https://rdcdn.com/rt?aid=XXXXX&e=1&img=1' ... />",
  "javascript_code": "<script> ... </script>",
  "portal_password": "Xu2!example",
  "created_at": "2026-08-07T18:31:02.558Z"
}

account_id is the ID you use on every other endpoint. Use pixel_code (image tag) or javascript_code (richer tracking) on the client's site — one of them, not both.

GET/v1/accounts

List your accounts

Returns every account you've created, newest first.

curl https://partners.traffic2leads.ai/v1/accounts \
  -H "Authorization: Bearer t2l_pk_XXXX..."
const res = await fetch('https://partners.traffic2leads.ai/v1/accounts', {
  headers: { 'Authorization': 'Bearer t2l_pk_XXXX...' },
});
const { accounts } = await res.json();
{
  "accounts": [
    {
      "account_id": 42,
      "client_name": "SG — Acme Roofing",
      "client_email": "owner@acmeroofing.com",
      "account_type": "B2C",
      "caps": { "monthly_lead_cap": 500, "daily_cap": null, "cap_reset_day": null },
      "delivery_schedule": null,
      "state_filters": null,
      "zip_filters": null,
      "status": "active",
      "webhook_url": "https://your-platform.com/hooks/t2l-leads",
      "created_at": "2026-08-07T18:31:02.558Z"
    }
  ]
}
GET/v1/accounts/{id}

Get one account

Same shape as the list entries, plus pixel_code and javascript_code so you can re-fetch the pixel any time. The portal_password is never included — it exists only in the create response.

PATCH/v1/accounts/{id}

Update account settings

Send any subset of the fields below — only what you send changes.

FieldNotes
monthly_lead_capNew monthly cap.
daily_capNew daily cap.
cap_reset_day1–28.
delivery_schedule1–5 (see create).
state_filters / zip_filtersReplaces the existing geo filters. Setting one type clears the other; you can't send both in one request.
curl -X PATCH https://partners.traffic2leads.ai/v1/accounts/42 \
  -H "Authorization: Bearer t2l_pk_XXXX..." \
  -H "Content-Type: application/json" \
  -d '{ "monthly_lead_cap": 1000, "state_filters": ["TX", "OK"] }'
await fetch('https://partners.traffic2leads.ai/v1/accounts/42', {
  method: 'PATCH',
  headers: {
    'Authorization': 'Bearer t2l_pk_XXXX...',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ monthly_lead_cap: 1000, state_filters: ['TX', 'OK'] }),
});

Responds 200 with the full updated account. PATCH /v1/accounts/{id}/limits also exists as a caps-only alias (accepts just the three cap fields).

PUT/v1/accounts/{id}/webhook

Set or replace the delivery webhook

Point the account's lead delivery at a (new) HTTPS endpoint at any time.

curl -X PUT https://partners.traffic2leads.ai/v1/accounts/42/webhook \
  -H "Authorization: Bearer t2l_pk_XXXX..." \
  -H "Content-Type: application/json" \
  -d '{ "webhook_url": "https://your-platform.com/hooks/t2l-leads-v2" }'
await fetch('https://partners.traffic2leads.ai/v1/accounts/42/webhook', {
  method: 'PUT',
  headers: {
    'Authorization': 'Bearer t2l_pk_XXXX...',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ webhook_url: 'https://your-platform.com/hooks/t2l-leads-v2' }),
});
POST/v1/accounts/{id}/pause  ·  /activate

Pause / resume lead delivery

POST /v1/accounts/{id}/pause stops lead collection for the account; POST /v1/accounts/{id}/activate resumes it. Use pause when a client offboards — there is no delete (contact us for permanent removal).

GET/v1/usage

Usage — lead counts

Per-account lead counts for billing and reporting. Two modes:

  • ?month=YYYY-MM — a calendar month (defaults to the current month if omitted)
  • ?start=YYYY-MM-DD&end=YYYY-MM-DD — any date range up to 366 days
curl "https://partners.traffic2leads.ai/v1/usage?start=2026-08-01&end=2026-08-31" \
  -H "Authorization: Bearer t2l_pk_XXXX..."
const res = await fetch(
  'https://partners.traffic2leads.ai/v1/usage?start=2026-08-01&end=2026-08-31',
  { headers: { 'Authorization': 'Bearer t2l_pk_XXXX...' } },
);
const usage = await res.json();
{
  "start": "2026-08-01",
  "end": "2026-08-31",
  "accounts": [
    { "account_id": 42, "client_name": "SG — Acme Roofing", "lead_count": 137 },
    { "account_id": 43, "client_name": "SG — Bright Dental", "lead_count": 88 }
  ],
  "total_leads": 225
}
GET/healthz

Health check

No auth required. Returns {"status":"ok","db":"ok"} when the API is fully operational — useful for your monitoring.

Webhook lead payload

When an account has a webhook configured, each identified lead is delivered to your endpoint as an HTTP POST with a JSON body (Content-Type: application/json). Respond with a 2xx quickly; do your processing async. Fields:

FieldDescription
FirstName / LastNameThe identified visitor's name.
EmailVerified email address.
EmailHashStable hashed identifier for the contact.
Address / Address2 / City / State / ZipPostal address, when resolved.
FirstPageViewUrl / LastPageViewUrlFirst and most recent page the visitor viewed.
PageViewUrlsComma-separated list of pages viewed.
TotalPageViewsNumber of page views in the visit(s).
InitialPageViewDate / LastPageViewDateTimestamps of the first and last page views.
ImpliedSecondsOnSiteEstimated time on site.
VisitDetailsAdditional visit attributes.
CampaignId / CampaignNameThe campaign that produced the lead (one per account).
AudienceId / AudienceNameThe pixel audience the lead came from.
RecordIdUnique delivery record ID — use it to de-duplicate.
SendDateWhen the lead was queued for delivery.

Errors & rate limits

Rate limit: 60 requests per minute per API key. Exceeding it returns 429 with a Retry-After header (seconds). All errors share one shape:

{ "error": { "code": "validation_error", "message": "monthly_lead_cap: monthly_lead_cap is required" } }
HTTPCodeMeaning
400validation_errorA field failed validation — the message names it.
400invalid_jsonThe request body isn't valid JSON.
401unauthorizedMissing, malformed, or revoked API key.
404not_foundThe account doesn't exist — or isn't yours.
409duplicate_emailYou already created an account with this client_email.
429rate_limitedToo many requests — honor Retry-After.
502upstream_errorThe platform rejected the operation; the message includes the reason.
500internal_errorUnexpected error — contact us if it persists.

Important notes

Credentials are yours to deliver No welcome email is ever sent to the client — by design, so your brand stays in front. The portal_password from the create response is the client's login for https://login.traffic2leads.ai; deliver it to them through your own channel. It is returned exactly once (plus the 24-hour idempotent replay window) and can never be retrieved afterward.
  • Billing starts at creation. There is no trial mode. Caps are your spend control — monthly_lead_cap is required everywhere.
  • Password resets are self-serve at login.traffic2leads.ai. Heads-up: the reset email arrives from a neutral platform domain (bit-sync.com), not a Traffic2Leads address.
  • No lead history over the API. Leads are delivered to the account's webhook (and visible in the account portal). The API reports counts, not lead records — so make your webhook endpoint reliable, and use RecordId to de-duplicate.
  • No delete endpoint. Pause an account to stop collection; contact us for permanent removal.
  • Test with validate_only — it exercises your full request, including duplicate detection, without creating a billed account.

Questions or a stuck integration? Contact your Traffic2Leads account manager.