← All articles
TutorialConfiguration

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

  1. Go to your agent's page
  2. Click Routines → New Routine
  3. Configure:
    • Name: Weekly Competitive Brief
    • Description: What this routine does
  4. 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:

  1. Create a Slack app with a slash command (e.g., /research)
  2. Set the Request URL to your Paperclip webhook endpoint
  3. When someone runs /research how does X work, Slack posts to the webhook
  4. 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 OK
  • forbid — 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 it
  • run — 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.