Paperclip Webhook and Routine Setup
Paperclip routines let you trigger agent runs on a schedule or from external events. Here's how to set up scheduled tasks (cron) and webhook-triggered workflows that respond to GitHub, Slack, or any HTTP source.
Deploy on Railway →What are routines?
Routines are recurring tasks in Paperclip. Each time a routine fires, it creates an execution issue assigned to the routine's agent. The agent picks it up in the normal heartbeat flow.
Routines support three trigger types:
- Schedule: Cron-based, fires on a time pattern
- Webhook: HTTP-triggered, fires when an external system sends a request
- API: Manual trigger, fires when you call the Paperclip API
Creating a scheduled routine
Via the dashboard
- Go to your agent's page
- Click Routines → New Routine
- Configure:
- Name:
Weekly Competitive Brief - Description: What this routine does
- Name:
- Add a Schedule trigger with a cron expression
Via the API
# Create the routine
curl -X POST "$PAPERCLIP_API_URL/api/companies/$COMPANY_ID/routines" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Weekly Competitive Brief",
"agentId": "YOUR_AGENT_ID",
"enabled": true,
"issueTemplate": {
"title": "Weekly competitive intelligence brief - {date}",
"description": "Research and summarize competitive activity this week. Check competitor blog posts, product updates, and community discussions."
}
}'
Note the routine ID from the response.
Add a schedule trigger
curl -X POST "$PAPERCLIP_API_URL/api/routines/ROUTINE_ID/triggers" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "schedule",
"config": {
"cron": "0 8 * * 1"
}
}'
This fires every Monday at 8am UTC.
Cron expressions for common schedules
| Schedule | Cron expression |
|---|---|
| Every day at 9am | 0 9 * * * |
| Every Monday at 8am | 0 8 * * 1 |
| Every weekday at 9am | 0 9 * * 1-5 |
| First of each month | 0 9 1 * * |
| Every 6 hours | 0 */6 * * * |
| Every hour | 0 * * * * |
Cron uses UTC. Adjust for your timezone: 0 9 * * * at UTC+2 would be 0 7 * * *.
Webhook triggers
Webhooks let external systems trigger Paperclip agent runs. When the webhook endpoint receives an HTTP POST, Paperclip creates a task for the routine's agent.
Create a webhook trigger
curl -X POST "$PAPERCLIP_API_URL/api/routines/ROUTINE_ID/triggers" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "webhook",
"config": {}
}'
The response includes a publicId — use it to construct the webhook URL:
POST https://paperclip.yourdomain.com/api/routine-triggers/public/{publicId}/fire
Any HTTP POST to this URL triggers the routine.
Sending data with the webhook
Include a JSON body to pass context to the agent:
curl -X POST "https://paperclip.yourdomain.com/api/routine-triggers/public/YOUR_PUBLIC_ID/fire" \
-H "Content-Type: application/json" \
-d '{
"event": "new_github_issue",
"issueTitle": "Bug: login fails on mobile",
"issueUrl": "https://github.com/org/repo/issues/123"
}'
The payload is included in the task description, so the agent can read it.
Webhook secret (security)
Rotate the webhook secret to prevent unauthorized triggers:
curl -X POST "$PAPERCLIP_API_URL/api/routine-triggers/TRIGGER_ID/rotate-secret" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY"
Store the secret and use it to sign webhook payloads from your external system.
Example: GitHub issue → Paperclip triage
Use GitHub Actions to fire a Paperclip webhook when new issues are opened:
# .github/workflows/paperclip-triage.yml
name: Paperclip Issue Triage
on:
issues:
types: [opened]
jobs:
triage:
runs-on: ubuntu-latest
steps:
- name: Trigger Paperclip triage
run: |
curl -X POST "${{ secrets.PAPERCLIP_WEBHOOK_URL }}" \
-H "Content-Type: application/json" \
-d '{
"event": "github_issue_opened",
"title": "${{ github.event.issue.title }}",
"body": "${{ github.event.issue.body }}",
"url": "${{ github.event.issue.html_url }}",
"author": "${{ github.event.issue.user.login }}"
}'
Set PAPERCLIP_WEBHOOK_URL in GitHub secrets. Your triage agent receives the issue details and creates a structured Paperclip task.
Example: Slack slash command → Paperclip agent
Set up a Slack app that fires a Paperclip webhook:
- Create a Slack app with a slash command (e.g.,
/research) - Set the Request URL to your Paperclip webhook endpoint
- When someone runs
/research how does X work, Slack posts to the webhook - Your research agent picks up the task and posts results back
This requires a middleware function to handle Slack's format and post the result back to Slack — a common pattern with n8n or a simple serverless function.
Concurrency and catch-up policies
When creating routines, configure:
concurrencyPolicy:
allow— multiple simultaneous runs OKforbid— skip new run if one is already running (recommended for most routines)replace— cancel existing run, start new one
catchUpPolicy:
skip— if scheduled run was missed (e.g., instance was down), skip itrun— run the missed executions on resume
For most Paperclip routines, concurrencyPolicy: forbid and catchUpPolicy: skip are appropriate.
Manual routine trigger (testing)
To fire a routine manually:
curl -X POST "$PAPERCLIP_API_URL/api/routines/ROUTINE_ID/run" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY"
Useful for testing without waiting for the scheduled trigger.
Ready to deploy?
Affiliate disclosure: this link may earn us a commission at no extra cost to you.
This is an independent guide. Paperclip Hosting is not affiliated with the official Paperclip project. Guide steps are based on real deployments and are subject to change as the software evolves.
Related articles
Deploy Paperclip on Fly.io
Run Paperclip on Fly.io with persistent storage, zero-downtime deploys, and global edge distribution — full setup guide.
Deploy Paperclip on Render
Host Paperclip on Render with a persistent disk, free SSL, and auto-deploys from GitHub — step-by-step setup guide.
Deploy Paperclip on Hetzner Cloud
Host Paperclip on Hetzner for as little as €4.51/month — one of the cheapest VPS options in Europe with great performance.
