Skip to Content

Zapier Integration

Connect Convoy to 6,000+ apps using Zapier. Automate AI content generation without writing any code.

Use Case: Automated Content Pipeline

A common workflow is using a Google Sheet as a prompt queue — when you add a new row with a topic or prompt, Zapier automatically sends it to Convoy for AI processing, and when the result is ready, it gets written back to your sheet (or sent to Slack, email, Notion, etc.).

Example scenarios:

  • Marketing team adds blog topics to a sheet → AI generates draft outlines → results posted to Slack
  • Support team logs customer questions → AI generates suggested responses → results written back to the sheet
  • Product team adds feature descriptions → AI generates user documentation → results sent via email

How This Works (in plain English)

Convoy is asynchronous — when you POST a prompt, you don’t get the AI response back in the same request. Convoy batches your prompt with others, processes it, and then calls you back with the result later. That means a complete Zapier setup is two Zaps, one for each direction:

┌─ ZAP 1 (Sender) ─┐ ┌─ ZAP 2 (Receiver) ─┐ │ │ │ │ You ─▶ │ New Sheet row │ ──── POST ───▶ Convoy ──── POST ──▶ │ Catch Hook ──▶ Save │ │ → Custom Request │ │ to Sheet/Slack/etc. │ └──────────────────┘ └─────────────────────┘ ↑ │ │ │ └────────────── Zap 2's webhook URL ─────────────────────┘ goes here as `callback_url`

You’ll build them in the same order the data flows: Step 1 sends the prompt, Step 2 catches the response, Step 3 wires them together. It’s normal for the very first Step 1 test to never produce a callback — Step 2 doesn’t exist yet. That’s expected.

Use the convoy-mock test model for this entire guide. Convoy ships a free, instant test model called convoy-mock that returns a synthetic AI response within ~1 minute and is not billed. Use it for every step here. Once your full pipeline works end-to-end, switch the model value to a real production model like claude-3-haiku.


Anatomy of the Convoy POST

This is the actual HTTP request Zap 1 makes. The Zapier “Custom Request” UI is just a visual wrapper around it — knowing this makes everything else click.

Endpoint: POST https://api.cnvy.ai/cargo/load

Headers:

HeaderValueWhere it comes from
Content-Typeapplication/jsonHardcoded in Zap 1
X-API-Keyconvoy_sk_...Your Convoy project API key — hardcoded (treat it like a password)

Body (annotated):

{ "params": { "model": "convoy-mock", // ← test model — free, ~1 min, no charge // Swap to "claude-3-haiku" etc. for production "max_tokens": 1024, // ← hardcoded "messages": [ { "role": "user", "content": "{{Topic}}" // ← MAPPED from Zap 1's trigger // (e.g. the Sheet row's "Topic" column) } ], "system": "{{System Prompt}}" // ← optional, mapped or hardcoded }, "callback_url": "PASTE_AFTER_STEP_2" // ← Zap 2's Catch Hook URL goes here. // Leave as a placeholder for Step 1 — you'll // come back and paste the real URL in Step 3. }

The four things you fill in:

  1. X-API-Key header — your Convoy project API key, once.
  2. messages[0].content — mapped from a field your trigger produces (the prompt itself).
  3. params.model — keep as convoy-mock while testing.
  4. callback_url — left as a placeholder for now. You’ll fill this in during Step 3, after Zap 2 exists.

When Zap 1 fires, Convoy responds immediately with a cargo_id (an acknowledgement). The actual AI text arrives later via POST to your callback_url — which is why Zap 2 exists.

See Prompts for the full payload reference — system prompts, multi-turn messages, temperature, and proven prompt patterns.


Prerequisites

  • A Convoy account with an active project
  • A project API key (starts with convoy_sk_) — see Authentication
  • A Zapier account (free tier works for testing)
  • A trigger source — a Google Sheet, Typeform, Airtable base, schedule, or anything Zapier supports

Step 1: Build Zap 1 — Send Prompts to Convoy

This is the Zap that watches your trigger source and POSTs each new prompt to Convoy. It’s the first thing in your data flow.

1a. Create a New Zap

  1. Go to zapier.com  and click Create Zap
  2. Name it “Convoy — Send AI Prompts”

1b. Add Your Trigger

This is your source of new prompts.

Google Sheets example:

  1. Select Google Sheets as the trigger app
  2. Choose New Spreadsheet Row as the trigger event
  3. Connect your Google account
  4. Select your spreadsheet and worksheet
  5. Test the trigger to pull in a sample row

Your sheet might look like this:

TopicSystem PromptStatusAI Response
Write a blog intro about AI in logisticsYou are a marketing copywriter.
Summarize our Q4 results for investorsYou are a business analyst.

The trigger fields you pull in here (Topic, System Prompt) are what you’ll map into the Convoy POST body in the next step.

1c. Add a Webhooks Action (Custom Request)

This action is the Convoy POST from the Anatomy section — you’re filling in those fields here.

  1. For the Action, search for and select Webhooks by Zapier
  2. Choose Custom Request as the action event
  3. Configure the request:

Method: POST

URL:

https://api.cnvy.ai/cargo/load

Headers:

Content-Type: application/json X-API-Key: convoy_sk_your_key_here

Replace convoy_sk_your_key_here with your actual Convoy project API key (Convoy dashboard → project settings).

Body:

{ "params": { "model": "convoy-mock", "max_tokens": 1024, "messages": [ { "role": "user", "content": "{{Topic from Google Sheets}}" } ], "system": "{{System Prompt from Google Sheets}}" }, "callback_url": "https://example.com/placeholder-fill-in-step-3" }

Map the values:

  • {{Topic from Google Sheets}} — Use Zapier’s field picker to insert your prompt column
  • {{System Prompt from Google Sheets}} — Map to your system prompt column (or hardcode a default)
  • model — keep as convoy-mock for testing
  • callback_urlleave as the placeholder URL for now. You’ll come back and replace it in Step 3 after Zap 2 exists. (A bogus URL won’t break Zap 1 — Convoy still accepts the request.)

1d. Test the Action

  1. Click Test to send a real request to Convoy
  2. You should get back:
    { "cargo_id": "crg_abc123def456", "status": "success", "message": "Cargo loaded successfully" }
    This means Convoy received your prompt. The actual AI response is not in this response — it’ll arrive later via callback.
  3. If you get an error, check:
    • Your API key is correct and active
    • The Content-Type header is exactly application/json
    • The body is valid JSON
    • The model is convoy-mock

What happens to this first test? Convoy is now processing the prompt and will try to call back the placeholder URL — which doesn’t exist yet. That’s fine. The test result will be lost, but you’ll see it tracked as callback_failed. You’re about to build Zap 2 to fix that.

1e. Turn On Zap 1

Once the test passes, turn on this Zap. It will now send every new sheet row to Convoy. None of those results will reach you yet — that’s what Step 2 is for.


Step 2: Build Zap 2 — Receive AI Results

This is the Zap that catches Convoy’s callback and routes the AI result back to your sheet (or wherever you want it).

2a. Create a New Zap

  1. Click Create Zap again
  2. Name it “Convoy — Receive AI Results”

2b. Add a Webhooks Trigger (Catch Hook)

  1. For the Trigger, search for and select Webhooks by Zapier
  2. Choose Catch Hook as the trigger event
  3. Click Continue — Zapier will generate a unique URL like:
    https://hooks.zapier.com/hooks/catch/123456/abcdef/
  4. Copy this URL. This is the value you’ll paste into Zap 1’s callback_url in Step 3.

Keep this webhook URL private. Anyone with this URL can send data to your Zap.

You can either wait for a real callback (after wiring up Step 3) or paste a sample payload now so you can map fields.

To map fields now without waiting, click Test trigger → if no events are found, click Skip test, or paste a sample by going to the trigger’s data structure and using:

{ "cargo_id": "crg_abc123def456", "success": true, "response": { "content": [{ "type": "text", "text": "Here is the generated content..." }], "model": "convoy-mock", "usage": { "input_tokens": 150, "output_tokens": 500 } }, "error": null }

2d. Add Your Destination Action

Where should the AI result go? Some popular choices:

Option A: Update the original Google Sheets row

  1. Select Google Sheets as the action app
  2. Choose Update Spreadsheet Row (so you write back to the row that triggered Zap 1)
  3. Connect your Google account and select your spreadsheet
  4. Use a Lookup step to find the row by cargo_id (you’ll need to write the cargo_id to the sheet from Zap 1 — see Tips for Production Use)
  5. Map the fields:
    • AI Response column → {{response__content[]text}}
    • Status column → {{success}}

Option B: Append a new row (simpler)

  1. Select Google SheetsCreate Spreadsheet Row
  2. Map:
    • Cargo ID{{cargo_id}}
    • AI Response{{response__content[]text}}
    • Model{{response__model}}

Option C: Post to Slack

  1. Select SlackSend Channel Message
  2. Map the message:
    ✅ AI Result Ready ({{cargo_id}}) {{response__content[]text}}

Option D: Send via Email

  1. Select Email by Zapier or Gmail
  2. Map the subject and body with {{response__content[]text}}

2e. Turn On Zap 2

Once configured, turn on this Zap. It’s now listening for callbacks from Convoy. But Convoy doesn’t know about it yet — that’s Step 3.


Step 3: Wire Them Together

The two Zaps are connected by one value: Zap 2’s Catch Hook URL (copied in Step 2b) goes into Zap 1’s callback_url field. That’s the entire connection.

3a. Edit Zap 1

  1. Open Zap 1 (the Sender)
  2. Find the Webhooks → Custom Request action
  3. In the Body, replace the placeholder callback_url value with the real Catch Hook URL from Step 2b:
    "callback_url": "https://hooks.zapier.com/hooks/catch/123456/abcdef/"
  4. Click Publish / Save to update the running Zap

3b. Test the Full Pipeline

  1. Add a new row to your Google Sheet with a prompt
  2. Wait for Zapier to detect the new row (1–15 min on free plans, instant on Premium)
  3. Confirm Zap 1 fired — its task history should show a 200 response with a cargo_id
  4. Wait ~1 minute for the convoy-mock test model to finish processing
  5. Confirm Zap 2 fired — its task history should show an incoming callback with the AI text
  6. Verify the result arrived at your destination (Sheet, Slack, etc.)

If Zap 1 fires but Zap 2 doesn’t, the most common cause is a wrong callback_url — go back to 3a and re-paste the URL exactly from 2b.

3c. Switch to a Production Model

Once the full pipeline works end-to-end on convoy-mock, you can swap in a real model:

  1. Open Zap 1 → Webhooks → Custom Request
  2. Change "model": "convoy-mock" to e.g. "model": "claude-3-haiku"
  3. Save and publish

Production models take longer (minutes to hours, depending on queue volume) and are billed based on tokens used.


Verifying Status

You can check the status of any request directly via the API:

curl -H "X-API-Key: convoy_sk_your_key_here" \ https://api.cnvy.ai/cargo/crg_abc123def456/tracking

Status progression: PENDINGBATCHEDPROCESSINGCOMPLETEDcallback_delivered

If you see callback_failed, your callback_url was wrong, the receiver Zap was off, or the webhook timed out.


Advanced Configuration

Using Multiple Models

Pick a model that matches the workload:

Use caseModelNotes
Testing pipeline end-to-endconvoy-mockFree, synthetic response in ~1 min, no charge
Short summaries, tagsclaude-3-haikuFast, cheapest production model
Blog posts, analysisclaude-3-sonnetGood balance of quality and cost
Complex research, creativeclaude-3-opusHighest quality

See Supported Models for the full list.

Dynamic Model Selection

If your sheet has a “Model” column, map it to the model field:

"model": "{{Model from Google Sheets}}"

Use convoy-mock in that column while testing each row, then switch.

Adding Temperature Control

For creative content, increase the temperature. For factual/structured output, keep it low:

{ "params": { "model": "claude-3-sonnet", "max_tokens": 2048, "temperature": 0.8, "messages": [ {"role": "user", "content": "Write a creative blog intro about..."} ] }, "callback_url": "https://hooks.zapier.com/hooks/catch/..." }

Handling Errors in Zap 2

Add a Filter step in Zap 2 after the Catch Hook:

  • Only continue if success equals true

Then add a separate path (using Zapier Paths) for failures:

  • If success equals false → Send an alert to Slack or email with the error field

Batch Processing Multiple Rows

If you want to process many rows at once, use Zapier’s Looping feature or a Schedule trigger that processes all new rows every hour.


Callback Payload Reference

When Convoy finishes processing, it sends this payload to your callback_url — i.e., this is what Zap 2 receives:

{ "cargo_id": "crg_abc123def456", "success": true, "response": { "id": "msg_01XFDUDYJgAACzvnptvVoYEL", "type": "message", "role": "assistant", "content": [ { "type": "text", "text": "Here is the generated content..." } ], "model": "convoy-mock", "stop_reason": "end_turn", "usage": { "input_tokens": 150, "output_tokens": 500 } }, "error": null }

Key fields for Zapier mapping:

Zapier Field PathDescription
cargo_idThe unique request ID
successtrue if processing succeeded
response__content[]textThe AI-generated text content
response__modelThe model that was used
response__usage__input_tokensTokens used for input
response__usage__output_tokensTokens used for output
errorError message (if success is false)

Troubleshooting

Zap 1 succeeds but Zap 2 never fires

Almost always a callback_url issue:

  • Confirm Zap 2 is turned on
  • Re-copy Zap 2’s Catch Hook URL and paste it back into Zap 1 (Step 3a) — make sure no quotes, spaces, or trailing slashes were lost
  • Hit the tracking endpoint — callback_failed means the URL was wrong or the receiver timed out

”Invalid API key” error

  • Verify your key starts with convoy_sk_
  • Check that the key hasn’t been revoked in the Convoy dashboard
  • Header name must be exactly X-API-Key (case-sensitive)

“Unknown model” error

  • Use convoy-mock for testing, or check the Supported Models page
  • Model IDs are case-sensitive (claude-3-haiku, not Claude-3-Haiku)

Zapier doesn’t detect new rows

  • Free Zapier plans poll every 15 minutes
  • Upgrade to a paid plan for 1–2 minute polling

Result is taking a long time

  • convoy-mock should return in ~1 minute. If it doesn’t, check the tracking endpoint
  • Production models batch and may take minutes to hours — that’s normal

Rate limit errors

  • Convoy allows 60 requests per minute and 500 per hour per project
  • Add a Delay step between requests when bulk-loading

Tips for Production Use

  1. Test on convoy-mock first. Always end-to-end test the full pipeline with the test model before swapping in a billed production model.
  2. Add a “Cargo ID” column to your sheet. Write cargo_id from Zap 1’s response into the row. Zap 2 can then use a Lookup step to update the correct row when the callback arrives.
  3. Add a “Status” column updated by Zap 2 (Submitted, Completed, Failed) so you can see at a glance what’s still in flight.
  4. Set up error notifications — route failed callbacks (success = false) to Slack or email.
  5. Start with claude-3-haiku for production (cheapest), then upgrade models as needed.

Cost efficiency: Convoy batches your requests together, which can reduce costs by up to 50% compared to making individual API calls. This makes it ideal for high-volume content generation workflows.

Last updated on