Connecting Zapier, Make, and Custom Backends
If you’re using Zapier, Make (formerly Integromat), n8n, a custom backend, or any other tool that can send an HTTP request, you can record claims, conversions, and visits in Advocate Loop without writing custom code.
This page shows you exactly what to send.
What you’ll need
Before configuring anything, gather two values from your Advocate Loop dashboard:
- API Key — found under Settings → API Keys. Keep this secret; treat it like a password.
- Brand ID — found alongside the API key on the same page.
You’ll send both as HTTP headers on every request.
Plan tiers
Some event types are available on all plans; others require Premier:
| Event | Starter | Growth | Premier |
|---|---|---|---|
Conversions (/track/conversion) | ✓ | ✓ | ✓ |
Refunds (/track/refund) | ✓ | ✓ | ✓ |
Claims (/track/claim) | — | — | ✓ |
Visits (/track/visit) | — | — | ✓ |
If you send a Premier-only event type on a lower-tier plan, the API returns a 403 response with a clear message.
The basics
Every request follows the same shape:
- URL:
https://api.advocateloop.com/api/v1/track/<event>(e.g./api/v1/track/conversion) - Method:
POST - Headers:
Content-Type: application/jsonX-API-Key: <your API key>X-Brand-ID: <your brand ID>
- Body: JSON payload (shape depends on the event type — see below)
If the request succeeds, you’ll get a 200 response with a JSON body like:
{ "success": true, "data": { /* event-specific details */ } }If something goes wrong, you’ll get a 4xx response with an explanation:
{ "success": false, "error": "what went wrong" }Recording a conversion
Use this when someone completes a purchase or other tracked outcome that should count against a referral.
Request
POST https://api.advocateloop.com/api/v1/track/conversionContent-Type: application/jsonX-API-Key: <your API key>X-Brand-ID: <your brand ID>
{ "customer_email": "buyer@example.com", "customer_name": "Jane Doe", "order_id": "ORD-12345", "order_total": 108.00, "tax": 8.00, "shipping": 10.00, "discount": 5.00, "referral_code": "JOHN123"}Fields
| Field | Required | Notes |
|---|---|---|
customer_email | yes | Used to match the conversion to a prior claim |
order_total | yes | The full order amount before any adjustments |
tax, shipping, discount | yes | Use 0 if not applicable. We need all three to compute the attributable revenue accurately. |
customer_name | no | Helpful for your records and dashboard display |
order_id | no | Your internal order identifier, for cross-referencing |
referral_code | no | Include if you know it. If omitted, we’ll match by customer_email against existing claims. |
Available on all plans.
Recording a refund
Use this when an order is refunded (in full or in part) so the conversion is updated accordingly.
Request
POST https://api.advocateloop.com/api/v1/track/refundContent-Type: application/jsonX-API-Key: <your API key>X-Brand-ID: <your brand ID>
{ "order_id": "ORD-12345", "refund_amount": 50.00, "total_refunded": 50.00, "is_full_refund": false, "refund_reason": "Customer changed mind on one item"}Fields
| Field | Required | Notes |
|---|---|---|
order_id | yes | Must match the order_id from the original conversion |
refund_amount | yes | The amount refunded in this transaction |
total_refunded | yes | The total refunded so far for this order (includes prior partial refunds) |
is_full_refund | yes | true if the order is now fully refunded |
refund_reason | no | Free-text reason, displayed in your dashboard |
Available on all plans.
Recording a claim — Premier only
Use this when a customer first claims a referral (signs up, requests a discount code, etc.). Most users don’t need to send this manually — the widget and plugin handle it automatically. Use this only if you’re integrating from a system that captures sign-ups outside the widget.
Request
POST https://api.advocateloop.com/api/v1/track/claimContent-Type: application/jsonX-API-Key: <your API key>X-Brand-ID: <your brand ID>
{ "referral_code": "JOHN123", "email": "newuser@example.com", "name": "Sam Smith", "phone": "+1-555-0100"}Fields
| Field | Required | Notes |
|---|---|---|
referral_code | yes | The code being claimed |
email | yes | The new user’s email |
name | no | Display name |
phone | no | Contact phone |
Premier plan only.
Recording a visit — Premier only
Track a click on a referral link from an external system. Most users don’t need this — visits are recorded automatically by al.js when a visitor lands on your site with a referral URL. Use this only if you’re tracking inbound traffic outside the browser (e.g., logging clicks from a custom email tool).
Request
POST https://api.advocateloop.com/api/v1/track/visitContent-Type: application/jsonX-API-Key: <your API key>X-Brand-ID: <your brand ID>
{ "referral_code": "JOHN123", "landing_page": "https://example.com/products/widget", "utm_source": "newsletter", "utm_medium": "email", "utm_campaign": "spring-sale"}Premier plan only.
Setting it up in Zapier
Zapier doesn’t have a dedicated Advocate Loop app yet. Use the Webhooks by Zapier built-in action:
- In your Zap, after your trigger step, add an action: Webhooks by Zapier → Custom Request
- Configure:
- Method:
POST - URL:
https://api.advocateloop.com/api/v1/track/conversion(or the event you’re sending) - Data Pass-Through: off (we’ll send JSON)
- Data: the JSON body for your event (see fields above). Use Zapier’s variable picker to map data from your trigger.
- Unflatten: Yes (so Zapier preserves your JSON structure)
- Headers: add
Content-Type: application/json,X-API-Key: <your key>,X-Brand-ID: <your brand ID>
- Method:
- Test the action with sample data. You should get a
200response withsuccess: true.
Common Zapier pitfall: if you map a numeric field from a previous step, Zapier may send it as a string. Numbers like order_total must be sent as JSON numbers, not strings. If you see validation errors, check the Zapier preview for fields wrapped in quotes that shouldn’t be.
Setting it up in Make (Integromat)
- Add an HTTP → Make a request module after your trigger
- Configure:
- URL:
https://api.advocateloop.com/api/v1/track/conversion - Method:
POST - Headers:
Content-Type: application/json,X-API-Key: <your key>,X-Brand-ID: <your brand ID> - Body type: Raw → JSON
- Request content: Your JSON body, with Make variables interpolated
- URL:
Setting it up from your backend
If you’re sending from your own server (Node, Python, PHP, Ruby, anything that can do HTTP), it’s just a POST with the headers and body above. There’s no SDK — the API is small enough that direct HTTP is the simplest path.
Node.js example
const response = await fetch('https://api.advocateloop.com/api/v1/track/conversion', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.ADVOCATELOOP_API_KEY, 'X-Brand-ID': process.env.ADVOCATELOOP_BRAND_ID }, body: JSON.stringify({ customer_email: 'buyer@example.com', order_id: 'ORD-12345', order_total: 108.00, tax: 8.00, shipping: 10.00, discount: 5.00, referral_code: 'JOHN123' })});
const result = await response.json();if (!result.success) { console.error('Failed to record conversion:', result.error);}Python example
import requestsimport os
response = requests.post( 'https://api.advocateloop.com/api/v1/track/conversion', headers={ 'Content-Type': 'application/json', 'X-API-Key': os.environ['ADVOCATELOOP_API_KEY'], 'X-Brand-ID': os.environ['ADVOCATELOOP_BRAND_ID'] }, json={ 'customer_email': 'buyer@example.com', 'order_id': 'ORD-12345', 'order_total': 108.00, 'tax': 8.00, 'shipping': 10.00, 'discount': 5.00, 'referral_code': 'JOHN123' })
result = response.json()if not result.get('success'): print(f"Failed: {result.get('error')}")Common issues
“401 Unauthorized” / “Invalid API key” — double-check the X-API-Key header value. Make sure there’s no leading/trailing whitespace and that you’re using the key from the right environment (production vs sandbox if you have separate keys).
“403 Feature not available” on claim/visit — these event types require Premier. Either upgrade your plan, or restructure your integration to use conversions/refunds (which are available on all plans).
“400 Bad Request” with field-specific error — the API tells you which field is missing or invalid. Read the error field of the response.
Numbers arriving as strings — particularly common from Zapier. JSON numbers must not be quoted. If order_total: "108.00" shows up in your request body, your tool is escaping the number. Check your tool’s settings for “data pass-through” or “raw JSON” options.
Webhook fires multiple times — most automation tools retry failed deliveries. Use the order_id field for conversions: if you send the same order_id twice, Advocate Loop won’t double-count it.
Security best practices
- Treat your API key like a password. Don’t commit it to source control. Don’t share it in support tickets unless explicitly asked (and rotate it after).
- Use HTTPS. All Advocate Loop endpoints require it; HTTP requests are rejected.
- Rotate keys if you suspect a leak or when a team member with access leaves.
- Limit access. Give each integration its own API key if you can, so you can revoke one without breaking others.