Integration Examples
Common custom action patterns and real-world integration examples
Custom actions require a Builder plan or higher.
Upgrade to Builder →
Body parameters are sent as top-level JSON keys. When you import a cURL whose body has nested objects or arrays, the importer creates dotted keys such as from.email, and those are sent as flat keys, not nested JSON. For an API that needs a nested body, replace those rows with one AI fills it in parameter of type Object or List (see Nested Body Fields).
Slack Notifications
Send messages to Slack channels via webhook.
Configuration
curl -X POST https://hooks.slack.com/services/{{var.SLACK_WEBHOOK_ID}} \
-H "Content-Type: application/json" \
-d '{
"text": "{{message}}",
"channel": "{{channel}}",
"username": "Chipp Bot"
}'Parameters
| Parameter | Source | Configuration |
|---|---|---|
message | AI fills it in | Message content to send. Type Text, Required |
channel | AI fills it in | Target channel. Type Text, Required off |
SLACK_WEBHOOK_ID | Application variable | Your Slack webhook ID, used in the URL |
Usage
“Send a message to #general saying the report is ready”
OpenAI Completions
Call OpenAI’s API for advanced processing.
Configuration
curl -X POST https://api.openai.com/v1/responses \
-H "Authorization: Bearer {{var.OPENAI_API_KEY}}" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4.1",
"input": "{{prompt}}",
"max_output_tokens": {{maxTokens}}
}'Parameters
| Parameter | Source | Configuration |
|---|---|---|
OPENAI_API_KEY | Application variable (secret) | Your OpenAI API key, used in the header |
input | AI fills it in | Text for OpenAI to process. Type Text, Required |
max_output_tokens | AI fills it in | Token limit. Type Whole number, Required off, sample 1000 |
Set Type to Whole number on max_output_tokens, so the AI sends a number and not the text "1000".
SendGrid Email
Send transactional emails via SendGrid.
Configuration
curl -X POST https://api.sendgrid.com/v3/mail/send \
-H "Authorization: Bearer {{var.SENDGRID_API_KEY}}" \
-H "Content-Type: application/json" \
-d '{
"personalizations": [{
"to": [{"email": "{{recipientEmail}}"}],
"subject": "{{subject}}"
}],
"from": {
"email": "{{var.FROM_EMAIL}}",
"name": "{{var.FROM_NAME}}"
},
"content": [{
"type": "text/html",
"value": "{{emailBody}}"
}]
}'Variables
SENDGRID_API_KEY = SG.abc123...
FROM_EMAIL = noreply@example.com
FROM_NAME = Your CompanyGoogle Sheets
Read and write data to Google Sheets.
Read Data
curl -X GET "https://sheets.googleapis.com/v4/spreadsheets/{{var.SHEET_ID}}/values/{{range}}" \
-H "Authorization: Bearer {{var.GOOGLE_API_KEY}}"Append Data
curl -X POST "https://sheets.googleapis.com/v4/spreadsheets/{{var.SHEET_ID}}/values/{{range}}:append" \
-H "Authorization: Bearer {{var.GOOGLE_API_KEY}}" \
-H "Content-Type: application/json" \
-d '{
"values": [[
"{{system.timestamp}}",
"{{system.user_id}}",
"{{data}}"
]]
}'Webhook with Dependencies
Multi-step workflow using action dependencies.
Step 1: Create User
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{var.API_KEY}}" \
-d '{
"name": "{{userName}}",
"email": "{{userEmail}}"
}'Returns: {"data": {"id": "user_123", "email": "john@example.com"}}
Step 2: Send Welcome Email
Use the user ID from Step 1:
curl -X POST https://api.example.com/emails \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{var.API_KEY}}" \
-d '{
"user_id": "{{userId}}",
"template": "welcome",
"send_at": "{{system.timestamp}}"
}'Parameter configuration for user_id:
- Source: Output from another action
- Action: Create User
- JSONPath:
$.data.id - Test value:
user_123(sent by Test Request, which has no earlier action output)
Save “Create User” first: the action list only shows saved actions. If the AI calls “Send Welcome Email” before “Create User” has run in the conversation, the call stops and the AI is told to run “Create User” first.
CRM Integration
Update customer records in your CRM.
Configuration
curl -X PATCH https://api.crm.com/v2/contacts/{{contactId}} \
-H "Authorization: Bearer {{var.CRM_API_KEY}}" \
-H "Content-Type: application/json" \
-d '{
"properties": {
"last_contact": "{{system.timestamp}}",
"last_message": "{{summary}}",
"status": "{{status}}"
}
}'AI Instructions
For summary parameter:
Summarize the key points from the conversation in 1-2 sentencesFor status parameter:
Determine status: 'interested', 'qualified', 'not-interested', or 'follow-up'Stripe Payment
Create payment intents via Stripe API.
Configuration
curl -X POST https://api.stripe.com/v1/payment_intents \
-u "{{var.STRIPE_SECRET_KEY}}:" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "amount={{amount}}¤cy=usd&customer={{customerId}}"Parameters
| Parameter | Source | Configuration |
|---|---|---|
STRIPE_SECRET_KEY | Application variable (secret) | Your Stripe secret key |
amount | AI fills it in | Amount in cents. Type Whole number |
currency | Fixed value | usd |
customer | AI fills it in | Stripe customer ID. Type Text |
The importer reads a form-encoded -d string as a single data parameter, so add these three body parameters by hand. It also turns -u into a fixed Authorization header that encodes the placeholder text itself, which Chipp cannot resolve. Delete that header and set the Auth tab to Basic Auth with the STRIPE_SECRET_KEY variable as the credential (Stripe uses the key as the username and an empty password). With the Content-Type: application/x-www-form-urlencoded header set, Chipp sends them form-encoded.
Weather API
Fetch weather data for user queries.
Configuration
curl -X GET "https://api.openweathermap.org/data/2.5/weather" \
-G \
--data-urlencode "q={{city}}" \
--data-urlencode "appid={{var.WEATHER_API_KEY}}" \
--data-urlencode "units=metric"Usage Examples
“What’s the weather in New York?” “Is it raining in London?”
GitHub Integration
Create issues in GitHub repositories.
Configuration
curl -X POST https://api.github.com/repos/{{var.GITHUB_OWNER}}/{{var.GITHUB_REPO}}/issues \
-H "Authorization: Bearer {{var.GITHUB_TOKEN}}" \
-H "Content-Type: application/json" \
-d '{
"title": "{{issueTitle}}",
"body": "{{issueBody}}",
"labels": {{labels}},
"assignees": {{assignees}}
}'Parameter Configuration
| Parameter | Source | Type | AI Instructions |
|---|---|---|---|
title | AI fills it in | Text | Create a concise title for the GitHub issue |
body | AI fills it in | Text | Write a detailed description of the issue |
labels | AI fills it in | List | Relevant labels, for example [“bug”, “urgent”]. Required off |
assignees | AI fills it in | List | GitHub usernames to assign. Required off |
Best Practices
1. Error Handling
Always return clear error messages:
{
"success": false,
"error": "API key invalid. Please check your credentials."
}2. Rate Limiting
Respect API rate limits:
- Add delays between requests
- Implement exponential backoff
- Cache responses when possible
3. Security
- Use HTTPS endpoints only
- Store credentials as secret variables
- Never log sensitive data
- Validate all inputs
4. Performance
- Paginate large result sets
- Use field selection to minimize data
- Implement timeouts (30s max)
- Cache frequently accessed data
5. Testing
- Test with various inputs
- Verify error handling
- Check edge cases
- Monitor response times