Skip to main content

Creating a Webhook Column

  1. Add a new column to any sheet
  2. Select “Webhook” as the column type
  3. Copy your unique webhook URL from the column settings
  4. Write your processing code in the column formula editor

Webhook URL Format

https://api.orangeslice.ai/webhook/{spreadsheet_id}/{column_id}
Your webhook URL is unique to the column and remains the same even if you rename the column.

Testing Your Webhook

Test with curl:
curl -X POST https://api.orangeslice.ai/webhook/{your-webhook-url} \
  -H "Content-Type: application/json" \
  -d '{"name": "Test User", "email": "[email protected]"}'
Or use tools like Postman, Insomnia, or webhook.site.

Common Patterns

Form Submission Handler

// Validate required fields
if (!webhook.body.email || !webhook.body.name) {
   return { success: false, error: "Name and email are required" };
}

// Add to leads sheet
webhook.addRootFieldsToSheet("Leads", true);

return { success: true, message: "Thank you for your submission!" };

With Query Parameters

// URL: https://api.orangeslice.ai/webhook/abc?source=facebook&campaign=summer

const source = webhook.query.source; // "facebook"
const campaign = webhook.query.campaign; // "summer"

await ctx.sheet("Leads").addRow({
   ...webhook.body,
   source: source,
   campaign: campaign,
});

return { success: true };

With Authentication

// Check for API key
const apiKey = webhook.headers["x-api-key"];
if (apiKey !== "your-secret-key") {
   return { error: "Unauthorized", status: 401 };
}

webhook.addRootFieldsToSheet("Leads", true);
return { success: true };

Deduplication

// Check if lead already exists
const existing = await ctx.getRowByValue("Leads", webhook.body.email, "email");

if (existing) {
   existing.set({ last_contact: new Date().toISOString() });
   return { success: true, action: "updated" };
}

webhook.addRootFieldsToSheet("Leads", true);
return { success: true, action: "created" };

With Enrichment

const { name, company } = webhook.body;

// Enrich with LinkedIn data
const linkedinUrl = await services.person.linkedin.findUrl({ name, company });

await ctx.sheet("Leads").addRow({
   ...webhook.body,
   linkedin_url: linkedinUrl,
   enriched_at: new Date().toISOString(),
});

return { success: true };

Error Handling

try {
   if (!webhook.body.email) {
      throw new Error("Email is required");
   }

   webhook.addRootFieldsToSheet("Leads", true);
   return { success: true };
} catch (error) {
   console.error("Webhook error:", error);
   return { success: false, error: error.message };
}

Debugging

Use console.log() to debug:
console.log("Method:", webhook.method);
console.log("Body:", webhook.body);
console.log("Headers:", webhook.headers);
console.log("Query:", webhook.query);
Console logs appear in the execution logs panel in the spreadsheet interface.