API & Integrations
Provider read feed (CollabOS) and the partner write API for creating raffles and pulling winners after draw.
A read-only, key-authed feed of Tessera raffle data for integrations (CollabOS is live on it): raffles, the person running them, structured requirements, and winners.
Authentication
Send your key on every request in the X-API-Key header (Authorization: Bearer <key> works too). Keys are issued per integration — contact the Tessera team to get one.
Ping is unauthenticated — use it for connectivity checks and monitoring.
List raffles
GET /provider/raffles — every raffle on Tessera, newest first, paginated.
| Parameter | Default | Description |
|---|---|---|
status | all | all, active, or ended |
limit | 100 | Page size, max 200 |
offset | 0 | Pagination offset |
updated_since | — | ISO timestamp — only raffles created or announced after this |
Raffle fields
| Prop | Type | Default |
|---|---|---|
raffleId | string | - |
raffleUrl | string | - |
title | string | - |
status | 'active' | 'ended' | - |
createdAt / startAt | ISO timestamp | - |
endAt | ISO timestamp | - |
endedAt | ISO timestamp | null | - |
updatedAt | ISO timestamp | - |
raffleType | 'standard' | - |
entryCount | number | - |
participantCount | number | - |
project | object | - |
allocation | object | - |
runner | object | - |
requirements | object[] | - |
Runner identity
Every raffle carries the actual person who runs it, keyed the way integrations need it:
| Field | Purpose |
|---|---|
runner.userId | Stable Tessera user ID |
runner.displayName | Human-readable name |
runner.discordId | Best key for automatic matching to your workspace members |
runner.discordUsername | Display and fallback identity |
runner.xUserId / runner.xUsername | X identity where connected |
createdBy, managedBy and drawnBy mirror runner — Tessera has a single raffle role (the creator). drawnBy is null until winners are drawn.
Requirements
The requirements array is pass-through from Tessera's own model — map what you need:
| Type | Meaning |
|---|---|
discord_linked | Entrant must link a Discord account |
discord_server | Role / server requirement — carries guildId, guildName, roleIds[], roleNames[] |
twitter_follow | X follow requirement |
twitter_tweet | X like / repost on a given tweet |
| … | Wallet checks and others pass through the same shape |
Winners
GET /provider/raffles/{raffleId} (or the URL slug) returns the raffle plus:
| Prop | Type | Default |
|---|---|---|
winners | object[] | - |
winnerCount | number | - |
winnersPublic | boolean | - |
Winners are gated by the team's own choice
Winner lists are included only when the hosting team publishes winners. A companion flag (enabled by Tessera) can widen that to all drawn raffles. Winner private codes and private winner notes are never part of the payload.
Errors
| Status | Meaning |
|---|---|
401 | Missing or invalid X-API-Key |
404 | No raffle with that ID or slug |
400 | Bad parameter (e.g. malformed updated_since) |
Rate guidance: paginate with limit ≤ 200 and walk offset; prefer updated_since for incremental polling.
Partner write API
For bots that create raffles and pull winners after draw (not the CollabOS read feed). Auth is the same header: X-API-Key. Each key is bound to one Tessera user and can only touch raffles on teams that user belongs to.
Create
POST /partner/v1/raffles — same fields as the site create form.
| Field | Default | Notes |
|---|---|---|
title | required | |
endsAt | required | ISO timestamp |
teamId | required | Must be a team the key’s user is on (GET /teams) |
winnerCount | 1 | |
requirements | [] | Same objects as the UI (type, label, value, guildId, …) |
requiredWalletType | "EVM" | EVM / SOL / BTC / null |
autoDrawWinners | false | Ended is not the same as drawn |
postDiscord | false | If true, needs Discord guild + channel on the raffle/team |
discord | — | { guildId, channelId, roleId, winnerChannelId } |
Status
GET /partner/v1/raffles/{id} is safe to poll anytime. It returns status (active / ended), endsAt, drawn (bool), announcedAt, entryCount. No winner list. No entries.
Winners
GET …/winners and …/winners.csv return the drawn Winner table only.
- While the raffle is live, or ended but not drawn:
409{ "detail": { "ready": false, "reason": "not_ended" | "not_drawn" } } - Never returns in-progress entrants as winners
- Partial / pending draws stay
not_drawnuntil slots are filled and none arepending
CSV columns: rank, username, discordId, xHandle, wallet, tierName, status.