This guide walks the whole system once: define an event in a schema, deploy it to an environment, publish it, watch it delivered, and give a customer their portal.
You need the repost CLI, a Repost account, and curl. No SDK is required for the walkthrough; the last step shows where the typed clients pick up.
The CLI is a single repost binary with the schema engine built in.
curl -fsSL https://releases.repost.sh/cli/install.sh | sh
repost auth loginrepost schema initinit asks which SDK language to generate and where the output should go, then scaffolds a repost/ directory:
repost/
├── schema.repost # your event definitions; starts with an example
├── .env # REPOST_SEND_API_KEY and REPOST_TOKEN, empty for now
└── .gitignore # keeps .env out of your repoYou'll fill in the two .env values in step 5.
Open repost/schema.repost. A schema has three parts: a payload model, an event-type catalog, and an event that ties them together.
model Order {
id String
currency String
}
type Order {
created
}
event OrderCreated {
type @type(Order.created)
data Order
timestamp DateTime
}This defines one event, order.created, carrying an Order payload and a timestamp. The schema language page covers every construct.
repost schema migrate dev --name initmigrate dev records the schema as a migration (committed to your repo and reviewable in git diff, like a database migration) and generates the typed client for the language you picked.
In the dashboard, create an environment. This is where your events go live, with its own registry, customers, and keys. Then open Settings → API Tokens inside it and create a token.
A token carries one or more scopes:
| Scope | What it allows |
|---|---|
publish | Publish messages into this environment. |
manage | Manage customers and endpoints through the API. |
schema:deploy | Deploy schemas from the CLI. |
Select all three for this walkthrough. In production, give each system its own narrowly scoped token. The token value starts with rp_ and is shown once. Copy it into repost/.env as both values:
REPOST_SEND_API_KEY="rp_..."
REPOST_TOKEN="rp_..."repost schema migrate deployThe CLI sends your committed migrations to the environment and prints the applied diff. order.created is now a live, versioned event type, visible under Event Types in the dashboard.
A customer is who you send to, identified by an externalId you choose. An endpoint is where their webhooks go. Creating an endpoint also creates the customer:
curl -X POST https://api.repost.sh/v1/customers/acme/endpoints \
-H "Authorization: Bearer $REPOST_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url": "https://acme.example.com/webhooks"}'The 201 response contains the endpoint and its whsec_... signing secret, which is returned only this once. By default the endpoint subscribes to every event type ("subscriptions": ["*"]).
No receiver handy? Create a bucket in the Receive tab and use its URL. The delivered webhook, signed headers included, will show up in the bucket's event history.
curl -X POST https://api.repost.sh/v1/messages \
-H "Authorization: Bearer $REPOST_SEND_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1001" \
-d '{
"type": "order.created",
"customerId": "acme",
"data": { "id": "order-1001", "currency": "EUR" }
}'{
"id": "msg_01JZX3NV7Q9WD9F2M6K4T8RSAB",
"type": "order.created",
"customerId": "acme",
"timestamp": "2026-07-17T12:00:00.000Z"
}Run it twice. The second call returns the same message with an Idempotent-Replay: true header instead of publishing a duplicate. Idempotency works this way for every publish.
Open Messages in the environment to follow the message to its delivery, attempt by attempt. On the receiving end, the webhook arrives as a signed Standard Webhooks request:
POST /webhooks HTTP/1.1
content-type: application/json
user-agent: Repost-Webhooks/1
webhook-id: msg_01JZX3NV7Q9WD9F2M6K4T8RSAB
webhook-timestamp: 1784289600
webhook-signature: v1,K5oZfzN95Z9UVu1EsPQqUIoRQOU...
{"type":"order.created","timestamp":"2026-07-17T12:00:00.000Z","data":{"id":"order-1001","currency":"EUR"}}If the endpoint is down, Repost retries for about a day before parking the delivery in the dead-letter queue.
Customers manage their own endpoints, secrets, and delivery logs in a hosted portal. Mint an access link:
curl -X POST https://api.repost.sh/v1/customers/acme/portal-access \
-H "Authorization: Bearer $REPOST_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'Open the returned url. This is the customer portal, with your branding, and no customer account is required.
Where to go next#
Models, event types, defaults, and what each line generates.
Replace the curl with a generated client in your language.
The retry schedule, the dead-letter queue, and replay.
Put your name and theme on the portal and event docs.
On This Page
Where to go next