Partner API v1

BitRaffle for developers

Two ways to integrate: a read-only REST API for your raffle data, and a drop-in widget that renders your live raffles on any site.

Get a key. Secret keys (sk_…) are issued per organisation by your account manager. A key resolves your organisation on every call — you only ever see your own data. Keys are shown once at creation; store them in your server's secrets, never in a browser.

1. Authentication

Send your secret key as a bearer token on every request:

Authorization: Bearer sk_live_your_key
ResponseMeaning
401 missing_api_keyNo Authorization header.
401 invalid_api_keyKey unknown or revoked.
403 insufficient_scopeKey lacks the scope named in required.
404 not_foundThe resource isn't yours (or doesn't exist).

Scopes: competitions:read, winners:read. Keys default to both.

2. Base URL

https://www.bitraffle.io/api/v1

Use the same host your key was issued for. Machine-readable spec: /api/v1/openapi.json (OpenAPI 3.0 — import it into Postman, Insomnia or an SDK generator).

3. Endpoints

GET /competitions — your active raffles

curl -H "Authorization: Bearer sk_live_your_key" \
     https://www.bitraffle.io/api/v1/competitions
{
  "data": [
    {
      "id": 42,
      "title": "Win a Rolex Submariner Date",
      "description": "…markdown…",
      "ticketPriceUSDCents": 2500,
      "paymentToken": "USDC",
      "maxTickets": 500,
      "ticketsSold": 103,
      "status": "active",
      "endDate": "2026-08-01T12:00:00.000Z",
      "imageUrl": "https://…",
      "payment": { "acceptedTokens": ["USDC"], "fiat": true, "fiatCurrency": "VND" }
    }
  ]
}

payment tells you how this raffle can be paid for right now — which crypto tokens, whether card/bank checkout is on, and the single fiat currency it charges. Use it to render the right checkout options.

GET /competitions/{id}

curl -H "Authorization: Bearer sk_live_your_key" \
     https://www.bitraffle.io/api/v1/competitions/42

Same shape, single object under data. Returns 404 for ids outside your organisation.

GET /winners — published winners + draw proof

curl -H "Authorization: Bearer sk_live_your_key" \
     https://www.bitraffle.io/api/v1/winners
{
  "data": [
    {
      "competitionId": 42,
      "competitionTitle": "Win a Rolex Submariner Date",
      "winnerWalletAddress": "0x1234…abcd",
      "wonAt": "2026-07-20T09:15:00.000Z",
      "draw": { "blockNumber": 6512233, "blockHash": "0x…", "winnerIndex": 87, "totalTickets": 500 }
    }
  ]
}

Every draw is provably fair: we commit to a future block before it exists, then winnerIndex = keccak256(blockHash · competitionId) mod totalTickets. The draw object is everything an entrant needs to re-compute the result independently.

Conventions

RuleDetail
MoneyIntegers, never floats. ticketPriceUSDCents is USD cents (2500 = $25.00).
DatesISO 8601 UTC strings.
EnvelopeSuccess payloads are always under data; errors carry error (+ message).
MethodReads only (GET). Entry creation isn't exposed — buyers check out on the hosted raffle pages.

Rate limits

Each API key gets its own budget — one partner's traffic can never slow another's:

HeaderMeaning
X-RateLimit-LimitRequests allowed per window.
X-RateLimit-RemainingRequests left right now.
X-RateLimit-ResetUnix seconds when your budget is fully restored.
Retry-AfterOnly on 429 — seconds to wait.
HTTP/1.1 429 Too Many Requests
Retry-After: 12

{ "error": "rate_limited", "message": "Too many requests …", "retryAfter": 12 }

The budget refills continuously rather than resetting on a fixed boundary, so steady traffic is never cliff-blocked. Cache responses for a minute where you can — raffle data doesn't change faster than that. Need a higher ceiling for a launch? Ask your account manager.


4. Embeddable widget — no key required

Drop your live raffles onto any page with one script tag. It injects a responsive iframe; nothing else on the host page is touched.

<script src="https://www.bitraffle.io/widget.js" data-org="house"></script>
AttributeRequiredValue
data-orgyesYour organisation slug — house.
data-competitionnoA competition id. Present → single-raffle mode (below); absent → the grid of all your active raffles.

The widget inherits your brand colour automatically, so embeds match your portal.

Live demo — this is the real widget, not a screenshot

Exactly what the snippet above renders, running right now with BitRaffle's live raffles. Cards update themselves as raffles sell and close.

your-website.com

…your page content…

…rest of your page…

Single-raffle mode — one prize, one campaign

Add data-competition to feature exactly one raffle: a bigger image, ticket price, a live countdown to the draw, sold progress and a branded call-to-action. Ideal for a landing page, a blog post or a campaign email's landing page.

<script src="https://www.bitraffle.io/widget.js"
        data-org="house"
        data-competition="68"></script>
your-campaign-page.com

…your campaign copy…

Checkout without leaving your page

Visitors pick a quantity in the widget and hit Enter raffle — checkout then opens in a secure popup on our domain: sign-in (email or wallet), the skill question, and payment (card/bank, QR or crypto). Your page never navigates away. When the purchase completes, the widget updates in place with a confirmation.

Why a popup, not an inline form? Card 3-D Secure pages, bank OTP screens and wallet extensions all refuse to run inside a third-party frame, and browsers block third-party cookies — so an inline checkout would break mid-payment. The popup runs first-party on our domain, which is also what lets buyers verify the address bar before paying. Same pattern as Stripe and PayPal. On mobile, where popups are unreliable, it falls back to a new tab automatically.

Nothing to implement — it's built into the widget. Fulfilment, notifications and the draw are handled for you.

Prefer your own frame? Embed https://www.bitraffle.io/embed/house (or /embed/house/competition/{id}) directly — set any width/height you like:

<iframe src="https://www.bitraffle.io/embed/house"
        style="width:100%;border:0;min-height:520px" loading="lazy"
        title="Raffles"></iframe>

Share images

Every raffle has a generated 1200×630 social card at https://www.bitraffle.io/og/competition/{id}.png — usable as an og:image on your own pages.


5. Request API access

Tell us about your integration and we'll issue a key. The widget needs no key — you can embed that today.


Already a partner? Contact your account manager. Spec: openapi.json.