Zapier's built-in Webhooks by Zapier action lets you call any HTTP API from inside a Zap without a pre-built connector. This guide shows you how to use it to convert data formats mid-workflow — for example, turning a Google Sheets CSV export into JSON before sending it to your app.
Prerequisites
- A free csvjson.tools account — your API key lives there
- A Zapier account (free tier is fine for testing)
The API endpoint
Every conversion goes through one endpoint:
POST https://us-central1-jsoncsv-3314b.cloudfunctions.net/api/convert
Required headers
| Header | Value |
|---|---|
| X-API-Key | Your key from the dashboard — starts with csvjson_sk_ |
| Content-Type | application/json |
Request body
{
"from": "csv",
"to": "json",
"input": "id,name\n1,Alice\n2,Bob",
"options": {
"pretty": true
}
}
Supported values for from / to: json · csv · xml · yaml · sql
The options object is always optional. See the options reference at the bottom of this page.
Example use case: Google Sheets → JSON → your app
Goal: Every time a new row is added to a Google Sheet, convert the row data to JSON and POST it to your application's webhook.
Step 1 — Trigger: New Row in Google Sheets
- Create a new Zap and click + Trigger
- Search for Google Sheets and select it
- Choose the New Spreadsheet Row event
- Connect your Google account, then pick your spreadsheet and sheet tab
- Click Test trigger — Zapier loads a sample row so you can map fields later
📸 Screenshot placeholder: Google Sheets trigger settings panel — spreadsheet dropdown, sheet dropdown, and a loaded sample row showing column values like id, name, email.
Step 2 — Action: Webhooks by Zapier (POST)
- Click + to add the next step
- Search for Webhooks by Zapier and select it
- Choose POST as the action event, then click Continue
📸 Screenshot placeholder: Zapier action picker with "Webhooks by Zapier" in the search box and the POST option highlighted in the results list.
Step 3 — Configure the webhook
URL
Paste the csvjson.tools endpoint:
https://us-central1-jsoncsv-3314b.cloudfunctions.net/api/convert
📸 Screenshot placeholder: The URL field in Zapier's Webhooks config, with the endpoint URL pasted in. The field is near the top of the "Set up action" panel.
Payload Type
Set this to json. This tells Zapier to send Content-Type: application/json and serialize the Data fields below as a JSON object.
📸 Screenshot placeholder: The "Payload Type" dropdown open, showing options Form, JSON, XML — with "json" selected and highlighted.
Important: If you leave Payload Type as "Form", the body will be URL-encoded and the API will reject it with a parse error.
Data (body fields)
Add the following key-value pairs. Use Zapier's field picker (the + icon) to insert dynamic values from previous steps.
| Key | Value |
|---|---|
| from | csv |
| to | json |
| input | (insert the CSV text from your previous step — see note below) |
Building the input field:
Google Sheets gives you individual cell values, not a raw CSV string. You have two options:
Option A — Assemble CSV inline (simple, works for a single row):
In the input value, type the header row manually, then use Zapier's "Text" formatting to append the row values:
id,name,email
{{id}},{{name}},{{email}}
Replace {{id}}, {{name}}, {{email}} with the actual field pills from your Google Sheets trigger.
Option B — Export the whole sheet (more powerful):
Add a Code by Zapier step before the webhook to fetch the sheet as CSV using the Google Sheets export URL, then pass that string as input. This converts the entire sheet at once.
📸 Screenshot placeholder: The Data section showing three rows: from = csv, to = json, and input = a multi-line value with the header row hard-coded and field pills for each column value from the Google Sheets step.
Headers
Click Headers to expand the section and add two entries:
| Key | Value |
|---|---|
| X-API-Key | csvjson_sk_your_key_here |
| Content-Type | application/json |
📸 Screenshot placeholder: The Headers section expanded, showing two rows. The X-API-Key row has a redacted key value. The Content-Type row shows application/json.
Tip: Store your API key in Zapier's credential store so it doesn't appear in plain text in every Zap.
Wrap Request in Array
Leave this off.
Unflatten
Leave this off — the API expects a flat JSON object, not nested keys.
Step 4 — Test the webhook step
Click Test action. If everything is configured correctly you'll see:
- Status: 200
- Body: A JSON string starting with
[{
📸 Screenshot placeholder: Zapier's test result panel showing a green "We sent a test" banner, HTTP status 200, and the response body containing formatted JSON.
If you see a 401 or 403, check that X-API-Key is set correctly. If you see 422, the input value is not valid CSV — check for missing line breaks between the header row and the data row.
Step 5 — Use the JSON output in the next step
Zapier exposes the API response as fields you can map into any later action.
- Add another action (e.g. HTTP by Zapier, Slack, Google Docs, or your own app)
- Click inside a text field and open the field picker
- Expand the Webhooks by Zapier step
- Select Body — this is the full converted output as a string
📸 Screenshot placeholder: Zapier's dynamic field picker showing the "Webhooks by Zapier" step expanded, with "Body" highlighted. The preview pane on the right shows a JSON array.
If the next step accepts raw JSON (e.g. another HTTP action): map Body directly into the body field and set Content-Type: application/json.
If the next step needs individual fields (e.g. a database insert): add a Code by Zapier step between them to JSON.parse(inputData.body) and return the individual fields.
More conversion examples
JSON array → CSV (flatten an API response before writing to Google Sheets)
{
"from": "json",
"to": "csv",
"input": "[{\"id\":1,\"name\":\"Alice\",\"address\":{\"city\":\"NYC\"}}]",
"options": {
"delimiter": ",",
"includeHeaders": true
}
}
Nested fields like address.city become their own column automatically.
CSV → XML
{
"from": "csv",
"to": "xml",
"input": "id,name\n1,Alice\n2,Bob",
"options": {
"rootElement": "records",
"itemElement": "record"
}
}
JSON → SQL INSERT statements
{
"from": "json",
"to": "sql",
"input": "[{\"id\":1,\"name\":\"Alice\"}]",
"options": {
"tableName": "users",
"ifNotExists": true
}
}
Options reference
CSV options
| Option | Type | Default | Description |
|---|---|---|---|
| delimiter | string | , | Column separator. Use \t for TSV. |
| includeHeaders | boolean | true | Whether the first row is treated as headers. |
| quoteAll | boolean | false | Wrap every field in quotes. |
JSON options
| Option | Type | Default | Description |
|---|---|---|---|
| pretty | boolean | true | Indent the output JSON. |
| indent | number | 2 | Spaces per indent level (when pretty is true). |
XML options
| Option | Type | Default | Description |
|---|---|---|---|
| rootElement | string | root | Tag name for the outer wrapper element. |
| itemElement | string | item | Tag name for each record element. |
SQL options
| Option | Type | Default | Description |
|---|---|---|---|
| tableName | string | data | The INSERT INTO table name. |
| ifNotExists | boolean | false | Prepend a CREATE TABLE IF NOT EXISTS statement. |
| batchSize | number | 1 | Rows per INSERT statement. |
Troubleshooting
| Error | Most likely cause | Fix |
|---|---|---|
| 401 Missing API key | X-API-Key header not set | Add it in the Headers section |
| 403 Invalid or revoked API key | Wrong key, or key was regenerated | Paste a fresh key from the dashboard |
| 422 Invalid JSON / PARSE_ERROR | The input value isn't valid for the from format | Click the Webhooks test step and inspect the Body preview |
| 429 Rate limit exceeded | Monthly call limit hit | Check your usage on the dashboard; upgrade for higher limits |
| Response Body is [] (empty array) | Valid CSV with no data rows | Confirm the input includes at least one row below the header |
| Zapier shows raw text, not parsed fields | Expected — the API returns plain text | Use JSON.parse in a Code step to access individual fields |
Rate limits
| Plan | Limit | |---|---| | Free | 500 calls / month | | Pro | 10,000 calls / month |
Your current usage is always visible on the dashboard.