API & Automation
Programmatically search messages, extract activation links in automated tests, manage projects, and configure granular API key permissions.
Sinkbox provides a full REST API designed specifically for CI/CD test automation, end-to-end testing frameworks (such as Playwright, Cypress, Pest, and Jest), and programmatic project management.
Automated Testing Quickstart
Authentication
Sinkbox supports four flexible authentication methods to fit different test runners and HTTP clients:
| Method | Header / Format | Example |
|---|---|---|
| Bearer Token | Authorization: Bearer <API_KEY> |
Authorization: Bearer sk_live_... |
| Basic Auth | Authorization: Basic base64(<USER>:<KEY>) |
-u username:key |
| X-API-Key Header | X-API-Key: <API_KEY> |
X-API-Key: sk_live_... |
| URL Credentials | /api/{username}/{key}/v1/... |
/api/user123/keyabc/v1/messages/latest |
Granular API Key Permissions
Every API key in Sinkbox can be restricted to specific ingestion channels and API capabilities. This ensures test runners, CI bots, and external tools only have the exact access they need.
Ingestion Service Permissions
Control which channels and drop-in endpoints the key can ingest into:
smtp— SMTP inbound gatewayresend,sendgrid— Email drop-instwilio_sms,twilio_voice,twilio_whatsapp46elks_sms,46elks_voicefcm,apns,onesignal— Push notificationsslack,teams,discord— Webhookssentry— Error report envelopesemail,sms,dump— Direct JSON API ingest
Action & Management Permissions
Control API access to stored items and project resources:
messages:read— Read messages, inspect links, and query the latest message.projects:read— List organization projects and check project status.projects:create— Create new projects programmatically within plan quotas.items:delete— [Destructive] Delete single messages or purge project inboxes.projects:delete— [Destructive] Delete projects permanently.
Security Note
Message Testing & Link Extraction Endpoints
1. Fetch the Latest Message
Retrieves the single newest message in the project matching your filter criteria. Perfect for fetching verification codes, activation emails, or password reset tokens in automated test flows.
GET https://ingest.sinkbox.dev/api/v1/messages/latest?to=user@example.com
Authorization: Bearer <API_KEY>
Available query parameters:
to/receiver— Filter by recipient email or phone number.from/sender— Filter by sender email or phone number.subject— Filter by subject text match.type— Filter by message type (email,sms,push,dump,sentry).unread=true— Limit to unread messages.tag— Filter by tag.
Example Response:
{
"id": "msg_9f83a0bc81d",
"type": "email",
"sender": "no-reply@myapp.com",
"receiver": "tester@example.com",
"subject": "Confirm your registration",
"content": "Welcome! Please verify your account at https://myapp.com/verify?token=abc123xyz",
"html_content": "<p>Welcome! Click <a href=\"https://myapp.com/verify?token=abc123xyz\">here</a> to verify.</p>",
"links": [
"https://myapp.com/verify?token=abc123xyz"
],
"activation_link": "https://myapp.com/verify?token=abc123xyz",
"tags": ["auth"],
"is_read": false,
"is_pinned": false,
"size_bytes": 1024,
"attachments": [],
"created_at": "2026-09-08T15:30:00+00:00"
}
2. Extract Message Links
Extracts all URLs found in both the HTML and plain-text message bodies and automatically determines the primary activation URL (matching verify, activate, confirm, token, register, magic link patterns).
GET https://ingest.sinkbox.dev/api/v1/messages/{id}/links
Authorization: Bearer <API_KEY>
3. Get Raw & HTML Message Content
Fetch raw MIME / textual payloads or rendered HTML directly:
GET https://ingest.sinkbox.dev/api/v1/messages/{id}/raw
GET https://ingest.sinkbox.dev/api/v1/messages/{id}/html
GET https://ingest.sinkbox.dev/api/v1/messages/{id}/attachments/{attachmentId}
Authorization: Bearer <API_KEY>
4. List & Search Messages
GET https://ingest.sinkbox.dev/api/v1/messages?to=user@example.com&page=1
Authorization: Bearer <API_KEY>
Outbound Webhooks
On Business and Custom plans, Sinkbox can automatically dispatch HTTP POST webhooks to your application whenever new messages arrive.
Webhook Security & Signatures:
Each webhook payload is signed with an HMAC-SHA256 signature using your webhook endpoint secret. The signature is sent in the header:
X-Sinkbox-Signature: sha256=<hmac_hash>
X-Sinkbox-Event: message.created
X-Sinkbox-Delivery: <uuid>
Webhook Payload Format:
{
"event": "message.created",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"created_at": "2026-09-08T22:30:00Z",
"data": {
"id": "msg_89f1a0b3e1",
"project_slug": "my-project",
"type": "email",
"sender": "noreply@auth.com",
"receiver": "user@example.com",
"subject": "Your Login OTP",
"tags": ["otp"],
"size_bytes": 1024,
"has_attachments": false,
"received_at": "2026-09-08T22:30:00Z"
},
"links": {
"message": "https://ingest.sinkbox.dev/api/v1/messages/msg_89f1a0b3e1",
"raw": "https://ingest.sinkbox.dev/api/v1/messages/msg_89f1a0b3e1/raw",
"html": "https://ingest.sinkbox.dev/api/v1/messages/msg_89f1a0b3e1/html"
}
}
Project & Lifecycle Management Endpoints
1. List Projects
List all projects in the API key's organisation.
GET https://ingest.sinkbox.dev/api/v1/projects
Authorization: Bearer <API_KEY>
2. Create a Project
Creates a new project dynamically within your plan allowance and generates a default API key.
POST https://ingest.sinkbox.dev/api/v1/projects
Authorization: Bearer <API_KEY>
Content-Type: application/json
{
"name": "E2E Test Run #412"
}
3. Delete a Project
DELETE https://ingest.sinkbox.dev/api/v1/projects/{slug}
Authorization: Bearer <API_KEY>
4. Purge Inbox Messages
Purges all messages (or filtered messages) from the project inbox to ensure a clean state between test suites.
DELETE https://ingest.sinkbox.dev/api/v1/messages
Authorization: Bearer <API_KEY>
Code Examples
Playwright / JavaScript:
import { test, expect } from '@playwright/test';
test('user registration and email confirmation', async ({ page, request }) => {
const email = `test-${Date.now()}@example.com`;
// 1. Submit signup form in the app
await page.goto('https://myapp.com/register');
await page.fill('input[name="email"]', email);
await page.click('button[type="submit"]');
// 2. Query Sinkbox API for the latest activation link
const response = await request.get('https://ingest.sinkbox.dev/api/v1/messages/latest', {
params: { to: email },
headers: { Authorization: `Bearer ${process.env.SINKBOX_API_KEY}` }
});
expect(response.ok()).toBeTruthy();
const message = await response.json();
expect(message.activation_link).toBeDefined();
// 3. Visit the confirmation link in the browser
await page.goto(message.activation_link);
await expect(page.locator('h1')).toContainText('Email Verified');
});
Pest / PHP:
use Illuminate\Support\Facades\Http;
test('sends verification email with valid activation link', function () {
$email = 'tester@example.com';
// 1. Trigger application action
$this->post('/register', ['email' => $email]);
// 2. Fetch the latest email from Sinkbox
$response = Http::withToken(config('services.sinkbox.key'))
->get('https://ingest.sinkbox.dev/api/v1/messages/latest', [
'to' => $email,
]);
expect($response->successful())->toBeTrue();
$activationLink = $response->json('activation_link');
expect($activationLink)->not->toBeNull()
->and($activationLink)->toContain('/verify?token=');
});