Creating a Job
This guide walks you through creating a job — a one-off HTTP request that is dispatched immediately or after a delay.
Via the dashboard
- Navigate to Jobs in the sidebar
- Click New Job
- Fill in the form:
- Queue — Select an existing queue from the dropdown, or select “New queue” and enter a name
- URL — The endpoint to call (e.g.,
https://api.yourapp.com/send-email) - Method — Select GET, POST, PUT, PATCH, or DELETE
- Optionally configure:
- Headers — Click Add Header to add key-value pairs (e.g.,
Authorization: Bearer ...) - Payload — Enter a JSON body. The field validates that the JSON is well-formed
- Callback URL — A URL that receives a POST when the job completes
- Delay — Seconds to wait before executing (0-86,400). Leave at 0 to run immediately
- Headers — Click Add Header to add key-value pairs (e.g.,
- Click Create
The job appears in the job list with status pending and is dispatched based on the delay.
Viewing a job
Navigate to Jobs > [job] to see the full detail page:
- Status — Current status (pending, processing, completed, failed)
- Final Status — Outcome of the retry chain (success, retrying, dead_lettered, etc.)
- Queue — The parent queue with link to its settings
- Attempt — Which attempt number this is (1 = original, 2+ = retries)
- Run Details — HTTP response status, body, headers, duration, and failure reason
Filtering and searching
On the Jobs page, use the controls to narrow results:
- Status filter — All, Pending, Completed, or Failed
- Queue filter — Show jobs for a specific queue
- Search — Find jobs by URL
Bulk operations
Select multiple jobs using the checkboxes, then choose:
- Bulk Delete — Remove selected jobs, or all failed/all pending
- Bulk Retry — Re-create selected failed jobs as new pending jobs
- Bulk Fire — Immediately dispatch selected pending jobs
Firing a pending job immediately
If a job is waiting for its scheduled time, click Fire Now on the job detail page to dispatch it right away.
Via the API
The primary way to create jobs programmatically, since they are typically triggered by events in your application.
curl
curl -X POST https://app.recurohq.com/api/jobs \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "queue": "notifications", "url": "https://api.yourapp.com/send-email", "method": "POST", "headers": { "X-Source": "recuro" }, "payload": { "to": "[email protected]", "template": "welcome" } }'PHP
// In a Laravel controller or service, after a user signs up:$response = Http::withToken(config('services.recuro.token')) ->post('https://app.recurohq.com/api/jobs', [ 'queue' => 'notifications', 'url' => 'https://api.yourapp.com/send-email', 'method' => 'POST', 'payload' => [ 'to' => $user->email, 'template' => 'welcome', ], ]);
$job = $response->json();// $job['job_id'] = 847, $job['scheduled_at'] = "2026-04-10T12:00:00+00:00"Node.js
// In an Express route handler, after creating an order:const response = await fetch('https://app.recurohq.com/api/jobs', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.RECURO_API_TOKEN}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ queue: 'notifications', url: 'https://api.yourapp.com/send-email', method: 'POST', payload: { to: user.email, template: 'welcome', }, }),});
const job = await response.json();console.log(`Scheduled job ${job.job_id} at ${job.scheduled_at}`);Python
import osimport requests
response = requests.post( 'https://app.recurohq.com/api/jobs', headers={'Authorization': f'Bearer {os.environ["RECURO_API_TOKEN"]}'}, json={ 'queue': 'notifications', 'url': 'https://api.yourapp.com/send-email', 'method': 'POST', 'payload': { 'to': user.email, 'template': 'welcome', }, },)
job = response.json()print(f"Scheduled job {job['job_id']} at {job['scheduled_at']}")Response
{ "success": true, "queue_id": 12, "job_id": 847, "scheduled_at": "2026-04-10T12:00:00+00:00", "message": "Scheduled successfully"}Delayed jobs
To run a job in the future, add a delay in seconds (0-86,400):
curl
curl -X POST https://app.recurohq.com/api/jobs \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "queue": "reminders", "url": "https://api.yourapp.com/remind", "method": "POST", "payload": { "user_id": 42, "message": "Your trial expires tomorrow" }, "delay": 86400 }'Node.js
// Schedule a reminder 30 minutes after signupawait fetch('https://app.recurohq.com/api/jobs', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.RECURO_API_TOKEN}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ queue: 'reminders', url: 'https://api.yourapp.com/remind', method: 'POST', payload: { user_id: user.id, type: 'onboarding_nudge' }, delay: 1800, // 30 minutes }),});Jobs with callbacks
To receive a notification when the job completes, add a callback_url:
curl -X POST https://app.recurohq.com/api/jobs \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "queue": "webhooks", "url": "https://partner.example.com/webhook", "method": "POST", "payload": { "event": "order.shipped" }, "callback_url": "https://api.yourapp.com/callback" }'Recuro POSTs the execution result to your callback URL when the job finishes. See Jobs > Completion callbacks for the payload format.
Next steps
- Schedule a Job (API) — Full API reference
- Queues — Configure retries, timeouts, and parallelism
- Jobs — Understand the job lifecycle
- Using the Dead Letter Queue — Handle failed jobs