Creating Triggers in Production

This guide explains how to create, manage, and operate triggers in a production TimeTriggers deployment. It covers API usage, authentication, best practices, and troubleshooting for production environments.

Overview

In production, triggers are created by sending HTTP requests to the TimeTriggers API at https://api.timetriggers.io. The process is the same as in development, but with additional considerations around:

  • Authentication: Using production API keys securely
  • Reliability: Ensuring triggers fire when expected
  • Observability: Monitoring trigger status and results
  • Quota: Managing your monthly call limits
  • Security: Protecting sensitive data in trigger configurations

Prerequisites

Before creating production triggers, ensure you have:

  1. A production account with TimeTriggers (sign up via the dashboard)
  2. API keys created in the dashboard for your production project
  3. Your target endpoint ready to receive the scheduled requests
  4. Understanding of the API basics

Creating Your First Production Trigger

The simplest way to create a production trigger is using the /schedule endpoint with curl:

curl -X POST https://api.timetriggers.io/schedule \
-H "ttr-api-key: ttr_YOUR_PRODUCTION_API_KEY" \
-H "ttr-url: https://your-production-service.com/webhooks/endpoint" \
-H "ttr-scheduled-at: 2026-10-17T14:30:00Z" \
-H "Content-Type: application/json" \
-d '{"event": "reminder", "userId": 12345}'

This schedules a one-shot trigger that will fire at 14:30 UTC on October 17, 2026.

Response

A successful request returns:

{
"triggerId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"scheduledAt": "2026-10-17T14:30:00.000Z",
"operation": "schedule",
"kind": "job",
"monthQuotaRemaining": 499
}

Store the triggerId — You need it to edit or cancel the trigger later.

Production Best Practices

1. Use Custom Keys for Idempotency

Always use ttr-custom-keyheader for triggers you may need to update:

curl -X POST https://api.timetriggers.io/schedule \
-H "ttr-api-key: ttr_YOUR_PRODUCTION_API_KEY" \
-H "ttr-url: https://your-service.com/reminders" \
-H "ttr-scheduled-at: 2026-10-18T09:00:00Z" \
-H "ttr-custom-key: user-12345-daily-reminder" \
-H "Content-Type: application/json" \
-d '{"userId": 12345}'

This allows you to update the trigger later by sending the same custom key with new parameters:

# Update the trigger time
curl -X POST https://api.timetriggers.io/schedule \
-H "ttr-api-key: ttr_YOUR_PRODUCTION_API_KEY" \
-H "ttr-url: https://your-service.com/reminders" \
-H "ttr-scheduled-at: 2026-10-19T09:00:00Z" \
-H "ttr-custom-key: user-12345-daily-reminder" \
-H "Content-Type: application/json" \
-d '{"userId": 12345}'

2. Use Tags for Organization and Policies

Tag your triggers to organize them and apply tag policies:

curl -X POST https://api.timetriggers.io/schedule \
-H "ttr-api-key: ttr_YOUR_PRODUCTION_API_KEY" \
-H "ttr-url: https://your-service.com/billing" \
-H "ttr-scheduled-at: now | add 1h" \
-H "ttr-tags: billing,critical,production" \
-H "ttr-custom-key: billing-invoice-67890" \
-H "Content-Type: application/json" \
-d '{"invoiceId": 67890}'

Then create a tag policy for production-critical triggers:

curl -X POST https://api.timetriggers.io/tag-policies \
-H "ttr-api-key: ttr_YOUR_PRODUCTION_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tag": "critical",
"maxConcurrent": 5,
"requestTimeoutSeconds": 60,
"retryMaxAttempts": 3,
"retryStrategy": "exponential",
"retryInitialDelaySeconds": 5,
"retryMaxDelaySeconds": 60,
"retryOn": "5xx+net"
}'

3. Use Recurring Triggers for Scheduled Jobs

For jobs that run on a schedule (cron), use recurring triggers:

# Send a daily digest at 8 AM UTC
curl -X POST https://api.timetriggers.io/schedule \
-H "ttr-api-key: ttr_YOUR_PRODUCTION_API_KEY" \
-H "ttr-url: https://your-service.com/digests/daily" \
-H "ttr-scheduled-at: cron(0 8 * * *)" \
-H "ttr-custom-key: daily-digest" \
-H "ttr-title: Daily Digest Email" \
-H "ttr-tags: digests,production" \
-H "Content-Type: application/json"

With a timezone:

# Send at 9 AM Paris time (CEST/ CET)
curl -X POST https://api.timetriggers.io/schedule \
-H "ttr-api-key: ttr_YOUR_PRODUCTION_API_KEY" \
-H "ttr-url: https://your-service.com/reports/morning" \
-H "ttr-scheduled-at: cron(0 9 * * *, Europe/Paris)" \
-H "ttr-custom-key: morning-report" \
-H "Content-Type: application/json"

See Recurring triggers for full cron syntax.

4. Secure Your API Keys

Never commit API keys to version control. Instead:

  • Store them in environment variables or secret managers
  • Use different keys for different environments (production, staging, development)
  • Rotate keys regularly
  • Delete unused keys

Example using environment variables:

export TTR_API_KEY="ttr_your_production_key_here"
curl -X POST https://api.timetriggers.io/schedule \
-H "ttr-api-key: $TTR_API_KEY" \
-H "ttr-url: https://your-service.com/endpoint" \
-H "ttr-scheduled-at: now | add 30m"

5. Monitor Your Triggers

Use the dashboard to:

  • View all your triggers and their status
  • Check execution history and response codes
  • Set up alerts for failures via Slack or email
  • Monitor your quota usage

For programmatic monitoring, you can use the dashboard API endpoints (requires session cookie):

# List all triggers (requires dashboard session)
curl https://timetriggers.io/api/jobs \
-H "Cookie: <your_session_cookie>"

6. Handle Timeouts and Retries

Configure appropriate timeouts and retry policies using tag policies:

# For API calls that may be slow
curl -X POST https://api.timetriggers.io/tag-policies \
-H "ttr-api-key: ttr_YOUR_PRODUCTION_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tag": "slow-api",
"requestTimeoutSeconds": 120,
"retryMaxAttempts": 5,
"retryStrategy": "exponential",
"retryInitialDelaySeconds": 10,
"retryMaxDelaySeconds": 300,
"retryOn": "5xx+net"
}'

See Tag policies for all available options.

Production Deployment Considerations

High Availability

The TimeTriggers production deployment runs multiple API replicas (4 by default) in Kubernetes. Each replica runs all background loops (scheduler, executor, materializer, reaper, alerter) and coordinates through PostgreSQL using row locks and advisory locks.

This means:

  • Triggers are reliably executed even if individual pods fail
  • The system automatically recovers from pod restarts
  • No manual intervention is needed for normal operations

Database Migrations

Production migrations are handled automatically via Helm pre-upgrade hooks. The migration job runs prisma migrate deploy with:

  • Backoff limit: 3 retries
  • Active deadline: 120 seconds
  • Restart policy: Never

If a migration fails, the Helm upgrade is rolled back automatically.

Monitoring and Health Checks

The production API exposes a health endpoint:

curl https://api.timetriggers.io/health

Response:

{"status": "ok", "schedulerStaleMs": 106, "materializerStaleMs": 246}

Kubernetes uses this for both liveness and readiness probes (30s and 10s intervals respectively).

Health check limitations: The health endpoint only checks that the scheduler and materializer loops are running. It does NOT verify:

  • The executor loop (triggers may pile up silently)
  • Database connectivity (a fresh process reports "ok" for 30-60 seconds)
  • Actual trigger firing

For full observability, monitor trigger execution in the dashboard.

Common Production Patterns

1. Delayed Processing

Schedule a trigger to fire after a delay:

# Fire in 1 hour
curl -X POST https://api.timetriggers.io/schedule \
-H "ttr-api-key: $TTR_API_KEY" \
-H "ttr-url: https://your-service.com/process" \
-H "ttr-scheduled-at: now | add 1h" \
-H "ttr-custom-key: user-12345-delayed-process" \
-H "Content-Type: application/json" \
-d '{"userId": 12345, "action": "process"}'

2. Retry with Exponential Backoff

Create a tag policy with exponential backoff for unreliable endpoints:

curl -X POST https://api.timetriggers.io/tag-policies \
-H "ttr-api-key: $TTR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tag": "unreliable-endpoint",
"maxConcurrent": 1,
"requestTimeoutSeconds": 30,
"retryMaxAttempts": 10,
"retryStrategy": "exponential",
"retryInitialDelaySeconds": 5,
"retryMaxDelaySeconds": 3600,
"retryOn": "5xx+net"
}'
curl -X POST https://api.timetriggers.io/schedule \
-H "ttr-api-key: $TTR_API_KEY" \
-H "ttr-url: https://unreliable-service.com/api" \
-H "ttr-scheduled-at: now" \
-H "ttr-tags: unreliable-endpoint" \
-H "ttr-custom-key: unreliable-call-1" \
-H "Content-Type: application/json" \
-d '{"data": "value"}'

3. Rate-Limited Triggers

Limit the rate of trigger execution to avoid overwhelming your endpoint:

curl -X POST https://api.timetriggers.io/tag-policies \
-H "ttr-api-key: $TTR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tag": "rate-limited",
"throughput": {
"rate": 10,
"per": 60
}
}'
# This trigger will fire at most 10 times per minute
curl -X POST https://api.timetriggers.io/schedule \
-H "ttr-api-key: $TTR_API_KEY" \
-H "ttr-url: https://your-service.com/api" \
-H "ttr-scheduled-at: now" \
-H "ttr-tags: rate-limited" \
-H "ttr-custom-key: rate-limited-call" \
-H "Content-Type: application/json" \
-d '{"data": "value"}'

4. Bulk Trigger Management

Use the /declare endpoint to manage multiple triggers declaratively:

curl -X POST https://api.timetriggers.io/declare \
-H "ttr-api-key: $TTR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tag": "my-batch",
"items": [
{
"customKey": "trigger-1",
"url": "https://your-service.com/endpoint-1",
"method": "POST",
"scheduledAt": "2026-10-18T10:00:00Z",
"headers": {"Content-Type": "application/json"},
"body": "{\"id\": 1}",
"title": "First trigger"
},
{
"customKey": "trigger-2",
"url": "https://your-service.com/endpoint-2",
"method": "POST",
"scheduledAt": "2026-10-18T11:00:00Z",
"headers": {"Content-Type": "application/json"},
"body": "{\"id\": 2}",
"title": "Second trigger"
}
]
}'

The /declare endpoint will:

  • Create triggers that don't exist
  • Update triggers that do exist with the same custom key
  • Cancel triggers with the tag that aren't in the list

See Declare a set of triggers for more details.

5. Bulk Apply for Atomic Operations

Use /bulk for atomic create/update/cancel operations:

curl -X POST https://api.timetriggers.io/bulk \
-H "ttr-api-key: $TTR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"upserts": [
{
"customKey": "important-trigger",
"url": "https://your-service.com/important",
"method": "POST",
"scheduledAt": "2026-10-18T12:00:00Z",
"headers": {"Content-Type": "application/json"},
"body": "{\"important\": true}",
"tags": ["critical"]
}
],
"cancels": [
{"customKey": "old-trigger"}
]
}'

See Bulk apply for the complete API.

Troubleshooting Production Issues

Trigger Not Firing

  1. Check the dashboard at https://timetriggers.io/dashboard/triggers

    • Is the trigger in "Scheduled" status?
    • Has it passed its due time?
    • Is it marked as "Skipped"?
  2. Verify the scheduled time:

    • Times are in UTC unless you specified a timezone
    • now fires immediately (within seconds)
    • Past-dated triggers are skipped unless you use ttr-run-missed: true
  3. Check for authentication issues:

    # Test your API key
    curl -X POST https://api.timetriggers.io/schedule \
    -H "ttr-api-key: $TTR_API_KEY" \
    -H "ttr-url: https://example.com/test" \
    -H "ttr-scheduled-at: now"
    # Should return 200 with a triggerId, or 401 if key is invalid
  4. Check tag policies:

    • A tag policy with maxConcurrent: 0 blocks all triggers with that tag
    • Throughput limits may delay trigger execution
  5. Check your target:

    • Is your endpoint reachable?
    • Does it return a success status code?
    • Are there any authentication issues with your target?

Trigger Fired But Target Didn't Receive It

  1. Check the execution details in the dashboard:

    • Look at the trigger page for execution history
    • Check the response status code and error messages
  2. Common issues:

    • Target URL is incorrect
    • Target requires headers that weren't sent
    • Target has rate limiting or IP restrictions
    • Network connectivity issues

High Trigger Failure Rate

  1. Review tag policies:

    • Increase retry attempts
    • Adjust retry delays
    • Check retry conditions (retry on 4xx vs 5xx)
  2. Check your target:

    • Is it returning appropriate error codes?
    • Are timeouts configured correctly?
  3. Monitor with alerts:

    • Set up failure alerts in the dashboard
    • Use Slack or email notifications

Production Checklist

Before deploying triggers to production:

  • [ ] API key is valid and has sufficient quota
  • [ ] Target endpoint is production-ready
  • [ ] All required headers are included
  • [ ] Scheduled times are correct (UTC vs local timezone)
  • [ ] Custom keys are set for triggers that need to be updated
  • [ ] Tags are set for organization and policy application
  • [ ] Tag policies are configured appropriately (timeouts, retries, concurrency)
  • [ ] Monitoring/alerting is in place
  • [ ] API keys are stored securely (not in code)
  • [ ] Quota usage is monitored
  • [ ] Error handling is implemented in your target

API Reference

All endpoints and their full documentation:

EndpointPurposeDocumentation
POST /scheduleCreate or update a triggerSchedule a trigger
DELETE /cancelCancel a triggerCancel a trigger
POST /declareDeclarative trigger managementDeclare a set of triggers
POST /bulkBulk operationsBulk apply
GET /jobsList triggers (dashboard)Dashboard API
GET /executionsList executions (dashboard)Dashboard API

Quota Management

Production accounts have monthly quota limits. Check your remaining quota:

curl -X POST https://api.timetriggers.io/schedule \
-H "ttr-api-key: $TTR_API_KEY" \
-H "ttr-url: https://example.com/test" \
-H "ttr-scheduled-at: now"
# Response includes "monthQuotaRemaining"

Or check in the dashboard under API Keys page.

See Quota for details on how quota works.

Security Best Practices

  1. Never expose API keys in client-side code

    • API calls should originate from your backend servers
    • Use environment variables or secret managers
  2. Use different keys for different environments

    • Separate keys for production, staging, development
    • This allows you to revoke one environment without affecting others
  3. Rotate keys regularly

    • Create new keys before decommissioning old ones
    • Update all services to use the new key
    • Delete the old key once all services are updated
  4. Don't put secrets in URLs

    • Credentials in URLs are visible in the dashboard
    • Use headers for authentication instead
  5. Use HTTPS

    • All target URLs should use HTTPS
    • API endpoints only accept HTTPS
  6. Monitor key usage

    • Review triggers created with each key periodically
    • Delete keys that created suspicious triggers

Performance Considerations

  1. Trigger creation rate: You can create triggers at any rate, but each /schedule call counts against your quota.

  2. Execution throughput: Tag policies control how quickly triggers execute. Without a throughput policy, triggers execute as quickly as possible.

  3. Concurrency: Use tag policy concurrency limits to prevent overwhelming your endpoints.

  4. Large payloads: Keep trigger bodies under 1 MB for reliable delivery.

  5. Header size: Keep total request headers under 16 KB.

Additional Resources

TimeTriggers — Schedule HTTP requests at any time.