Skip to Content
Developer HubGuides & TutorialsFreebetsAdmin Third-Party Integration

Third-Party integration overview

You can manage the configuration and issuance of free bets through our admin panel. Additionally, we provide a special API that allows for third-party integration with your systems without the need to use our admin panel.

Please refer to the Bonus External section in the documentation .

Authorization

Access to the API is provided via an API token, which should be included in the x-bonus-api-token header. To obtain a token, please contact us .

Example:

curl -X 'POST' \ 'https://api.onchainfeed.org/api/v1/public/bonus/external/offer/freebet/create' \ -H 'accept: application/json' \ -H 'x-bonus-api-token: api-token' \ -H 'Content-Type: application/json'

General methods

Create freebet offer

Endpoint: /api/v1/public/bonus/external/offer/freebet/create

Request: CreateFreebetOfferDto

Response: OfferResponse

Example:

curl -X 'POST' \ 'https://api.onchainfeed.org/api/v1/public/bonus/external/offer/freebet/create' \ -H 'accept: application/json' \ -H 'x-bonus-api-token: api_token' \ -H 'Content-Type: application/json' \ -d '{ "name": "Offer Name", "key": "offer_key", "publicCustomData": { "color": 2321, "publicName": "Test freebet" }, "description": "description text", "settings": { "bonusType": "AllWin", "feeSponsored": true, "betRestriction": { "betType": "All", "minOdds": "1.5", "maxOdds": "2.0" }, "eventRestriction": { "eventStatus": "All", "eventFilter": { "exclude": false, "filter": [ { "sportId": "1", "leagues": [ "Premier League", "La Liga" ], "markets": [ { "marketId": 1, "gamePeriodId": 1, "gameTypeId": 1 } ] } ] } }, "periodOfValidityMs": 86400000 } }'

Distribution bonus by offer

Endpoint: /api/v1/public/bonus/external/create

Request: CreateBonusDto

Response: BonusesResponse

Example:

curl -X 'POST' \ 'https://api.onchainfeed.org/api/v1/public/bonus/external/create' \ -H 'accept: application/json' \ -H 'x-bonus-api-token: api_token' \ -H 'Content-Type: application/json' \ -d '{ "offerId": "f3f2e850-b5d4-11ef-ac7e-96584d5248b5", "poolId": "5cf0db52-1a86-46d3-abbf-df262c5be39c", "recipients": [ { "address": "f3f2e850-b5d4-11ef-ac7e-96584d5248b5", "amount": "100" } ], "campaignGroup": "campaign-group-1" }'

Get offers list

Endpoint: /api/v1/public/bonus/external/offer/list

Response: OffersResponse

Example:

curl -X 'GET' \ 'https://api.onchainfeed.org/api/v1/public/bonus/external/offer/list' \ -H 'accept: application/json' \ -H 'x-bonus-api-token: api_token'

Get bonuses

Endpoint: /api/v1/public/bonus/external/list

Parameters:

  • status (optional): Available or Used
  • source (optional): which issuance source to list, All, Manual or PromoCode (BonusSource). All is the default when omitted
  • page (optional): 1-based page number, at most 10000
  • perPage (optional): number of bonuses per page, from 1 to 200. When omitted, the list is not paginated and returns every bonus

Response: BonusesResponse

Each bonus carries isPromoCode and promoCode: whether it was issued by activating a promo code, and which code. See BonusResponse.

Example:

curl -X 'GET' \ 'https://api.onchainfeed.org/api/v1/public/bonus/external/list' \ -H 'accept: application/json' \ -H 'x-bonus-api-token: api_token'

Only the bonuses issued by promo codes:

curl -X 'GET' \ 'https://api.onchainfeed.org/api/v1/public/bonus/external/list?source=PromoCode' \ -H 'accept: application/json' \ -H 'x-bonus-api-token: api_token'

Promo codes

A promo code grants a freebet from an offer and a pool to every bettor who activates it. You create and manage codes with the methods below; bettors activate them on the public endpoint, see the Promo codes guide.

⚠️

amount is in the base units of the pool’s token: "5000000" is 5 USDT on a 6-decimal token. It is copied as is into every freebet the code issues.

Create promo code

Endpoint: POST /api/v1/public/bonus/external/promo-code/create

Request: CreatePromoCodeDto

Response: PromoCodeResponse

The code is trimmed and upper-cased, must consist of A-Z, 0-9, - and _, 1 to 32 characters, and must be unique.

Example:

curl -X 'POST' \ 'https://api.onchainfeed.org/api/v1/public/bonus/external/promo-code/create' \ -H 'accept: application/json' \ -H 'x-bonus-api-token: api_token' \ -H 'Content-Type: application/json' \ -d '{ "code": "SUMMER26", "offerId": "00000000-0000-4000-8000-000000000001", "poolId": "00000000-0000-4000-8000-000000000002", "amount": "5000000", "maxActivations": 100, "expiresAt": "2027-06-30T00:00:00.000Z" }'

Get promo codes

Endpoint: GET /api/v1/public/bonus/external/promo-code/list

Parameters:

  • offerId (optional): only the codes of this offer
  • status (optional): Active or Deactivated (PromoCodeStatus)

Response: PromoCodesResponse

Returns every code of the product, newest first, with no pagination. Active only means the code is not deactivated: an expired or used-up code is still Active, so compare expiresAt with the current time and activationsCount with maxActivations yourself.

Example:

curl -X 'GET' \ 'https://api.onchainfeed.org/api/v1/public/bonus/external/promo-code/list?status=Active' \ -H 'accept: application/json' \ -H 'x-bonus-api-token: api_token'

Update promo code

Endpoint: PATCH /api/v1/public/bonus/external/promo-code/update

Request: UpdatePromoCodeDto

Response: PromoCodeResponse

Example:

curl -X 'PATCH' \ 'https://api.onchainfeed.org/api/v1/public/bonus/external/promo-code/update' \ -H 'accept: application/json' \ -H 'x-bonus-api-token: api_token' \ -H 'Content-Type: application/json' \ -d '{ "id": "00000000-0000-4000-8000-000000000003", "expiresAt": "2027-12-31T00:00:00.000Z" }'

Rules:

  • Send only the fields you change.
  • code can never change. A body that contains code is rejected with HTTP 400.
  • After the first activation, offerId, poolId and amount are locked. A body that contains any of them is refused, even with the unchanged value, with bonus.update_promo_code_with_activations_error.
  • After the first activation, maxActivations and expiresAt stay editable, but maxActivations cannot go below activationsCount. Otherwise the request is refused with bonus.promo_code_max_activations_below_used_error.

Deactivate promo code

Endpoint: PATCH /api/v1/public/bonus/external/promo-code/deactivate

Request: DeactivatePromoCodeDto

Response: PromoCodeResponse

Deactivation is final: a deactivated code can never be reactivated. Freebets already issued stay valid.

Example:

curl -X 'PATCH' \ 'https://api.onchainfeed.org/api/v1/public/bonus/external/promo-code/deactivate' \ -H 'accept: application/json' \ -H 'x-bonus-api-token: api_token' \ -H 'Content-Type: application/json' \ -d '{ "id": "00000000-0000-4000-8000-000000000003" }'

Errors

Business errors are returned with HTTP 409 and a body { code, message }. Request validation errors are returned with HTTP 400 and a body { message: string[] }.

CodeWhen
bonus.promo_code_code_conflictA code with that value already exists
bonus.promo_code_invalid_codeThe code does not match the allowed format
bonus.promo_code_invalid_amountamount is not positive
bonus.promo_code_expires_at_in_pastexpiresAt is not in the future
bonus.promo_code_offer_not_freebetThe offer is not a freebet offer
bonus.promo_code_not_foundNo such promo code
bonus.promo_code_access_deniedThe promo code belongs to another product
bonus.update_promo_code_with_activations_errorofferId, poolId or amount sent for a code that already has activations
bonus.promo_code_max_activations_below_used_errormaxActivations is below activationsCount

The offer and pool not-found and access-denied errors are returned the same way.

Statistic methods

These methods display statistics on the bonuses issued

Get bonus statistics by campaign

Endpoint: /api/v1/public/bonus/external/statistics/freebet/by-campaign

Response: BonusStatisticsByCampaignResponse

Example:

curl -X 'GET' \ 'https://api.onchainfeed.org/api/v1/public/bonus/external/statistics/freebet/by-campaign' \ -H 'accept: application/json' \ -H 'x-bonus-api-token: api_token'

Get bonus statistics by pool

Endpoint: /api/v1/public/bonus/external/statistics/freebet/by-pool

Response: BonusStatisticsByPoolResponse

Example:

curl -X 'GET' \ 'https://api.onchainfeed.org/api/v1/public/bonus/external/statistics/freebet/by-pool' \ -H 'accept: application/json' \ -H 'x-bonus-api-token: api_token'

Get pools list

Endpoint: /api/v1/public/bonus/external/pool/list

Response: PoolsResponse

Example:

curl -X 'GET' \ 'https://api.onchainfeed.org/api/v1/public/bonus/external/pool/list' \ -H 'accept: application/json' \ -H 'x-bonus-api-token: api_token'

Utils methods

These methods function as utilities for collecting supplementary information required when constructing an eventFilter

Get unique markets combinations

Endpoint: /api/v1/public/bonus/external/utils/markets-combinations

Parameters:

  • sportId (required): Sport ID

Response: SportsUniqueMarketsCombinationsResponse

Example:

curl -X 'GET' \ 'https://api.onchainfeed.org/api/v1/public/bonus/external/utils/markets-combinations?sportId=33' \ -H 'accept: application/json' \ -H 'x-bonus-api-token: api_token'

Get actual sport IDs

Endpoint: /api/v1/public/bonus/external/utils/markets-combinations/sports

Response: ActualSportIdsResponse

Example:

curl -X 'GET' \ 'https://api.onchainfeed.org/api/v1/public/bonus/external/utils/markets-combinations/sports' \ -H 'accept: application/json' \ -H 'x-bonus-api-token: api_token'

Get actual leagues

Endpoint: /api/v1/public/bonus/external/utils/leagues

Parameters:

  • sportIds (optional): Array of sport IDs
  • startsAtFrom (optional): From time (timestamp)
  • startsAtTo (optional): To time (timestamp)

Response: ActualLeaguesResponse

Example:

curl -X 'GET' \ 'https://api.onchainfeed.org/api/v1/public/bonus/external/utils/leagues?sportIds=33&startsAtFrom=1742216019000&startsAtTo=1743339219000' \ -H 'accept: application/json' \ -H 'x-bonus-api-token: api_token'