Creating events
Events record activity inside a workspace. Each event has a type string (for example, invoice.paid) and a JSON payload. Events are immutable after creation.
You need an API key with the events:write scope. See Event lifecycle for how events flow to webhooks.
- TypeScript
- JavaScript
- cURL
import { Harbor } from '@harbor/sdk';
const harbor = new Harbor({ secretKey: process.env.HARBOR_SECRET_KEY });
const event = await harbor.events.create({
workspaceId: 'ws_018f3a2e4b9c',
type: 'invoice.paid',
payload: {
invoiceId: 'inv_0192ac4e8b1d',
amountCents: 4200,
},
});
console.log(event.id); // evt_01hzy9q7x8f4
const { Harbor } = require('@harbor/sdk');
const harbor = new Harbor({ secretKey: process.env.HARBOR_SECRET_KEY });
const event = await harbor.events.create({
workspaceId: 'ws_018f3a2e4b9c',
type: 'invoice.paid',
payload: {
invoiceId: 'inv_0192ac4e8b1d',
amountCents: 4200,
},
});
console.log(event.id);
curl https://sandbox.api.harbor.dev/v1/events \
-X POST \
-H "Authorization: Bearer hb_test_xxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: inv_0192ac4e8b1d-paid" \
-d '{
"workspace_id": "ws_018f3a2e4b9c",
"type": "invoice.paid",
"payload": {
"invoice_id": "inv_0192ac4e8b1d",
"amount_cents": 4200
}
}'
Idempotency
Pass an idempotency key when retries could create duplicate events:
await harbor.events.create(
{
workspaceId: 'ws_018f3a2e4b9c',
type: 'invoice.paid',
payload: { invoiceId: 'inv_0192ac4e8b1d', amountCents: 4200 },
},
{ idempotencyKey: 'inv_0192ac4e8b1d-paid' },
);
Harbor returns the same event if you replay the request with the same key within 24 hours. After expiry, the key can be reused for a new event.
Sample response (201 Created)
{
"id": "evt_01hzy9q7x8f4",
"type": "invoice.paid",
"workspace_id": "ws_018f3a2e4b9c",
"payload": {
"invoice_id": "inv_0192ac4e8b1d",
"amount_cents": 4200
},
"created_at": "2026-05-25T12:00:00Z"
}
Retrieve an event
const event = await harbor.events.retrieve('evt_01hzy9q7x8f4');
Use retrieval to confirm persistence after a write or to audit payload contents before replaying to a consumer.
Backfill and replay
If a downstream system missed events, see Event lifecycle § Event replay.
Event types are plain strings. Document your team's naming convention (for example, resource.action) so webhook filters stay predictable.
Common mistakes
- Creating events in the wrong workspace. Always pass the workspace ID explicitly.
- Omitting
events:writeon restricted keys. See Managing API keys. - Sending payloads larger than 256 KB. Store blobs elsewhere and reference them by ID.
- Retrying
createwithout an idempotency key after a timeout. You may duplicate events.
Next steps
Continue to Webhook delivery. Method signatures in Events (SDK reference).