Developers

BidX Connect API

Bring your tenders and awarded suppliers into the systems you already run. One token, plain JSON, and examples you can paste.

Sandboxhttps://sandbox.zangupay.com

On this page

Getting started

Introduction

The BidX Connect API lets your ERP, finance or supplier systems read your tenders and the suppliers you award, so procurement data flows without re-keying.

It is a JSON-over-HTTPS REST API. Every response wraps its payload in a data field. During the preview, all calls go to the sandbox; production access is enabled per organisation on request.

Base URL · Sandbox
https://sandbox.zangupay.com

Getting started

Authentication

The API uses the OAuth 2.0 client credentials flow. An administrator creates credentials in the BidX buyer portal under Admin → API keys & integrations.

  • The client secret is shown once. Store it in a secrets manager; BidX keeps only a hash and cannot show it again.
  • Tokens last 20 hours (expires_in seconds). Cache one and request a new token when it expires.
  • Call the API from your servers only. Never ship credentials in a browser or mobile app.
Client credentials flow
# 1. Exchange your credentials for a token (valid 20 hours)
curl --request POST "https://sandbox.zangupay.com/v1/oauth/token" \
  --header "Content-Type: application/json" \
  --data '{"client_id": "…", "client_secret": "…", "grant_type": "client_credentials"}'

# 2. Send it on every call
curl "https://sandbox.zangupay.com/v1/connect/bid" \
  --header "Authorization: Bearer $BIDX_ACCESS_TOKEN"

Getting started

Errors

Failed calls return a non-2xx status and an error object. Branch on error.code, which is stable; error.en is a readable message that may change.

HTTPerror.codeWhen
400invalid_requestA required field is missing.
401invalid_access_tokenThe token is missing or expired.
401invalid_access_token_formatThe header is not Bearer <token>.
500not_knownSomething failed on our side; retry with backoff.
Error response
{
  "success": false,
  "http_code": "401",
  "error": {
    "code": "invalid_access_token",
    "en": "No access token submitted."
  }
}

Getting started

Conventions & limits

  • IDs are 24-character hexadecimal strings. Treat them as opaque.
  • Dates read like 30-Sep-2026 07:07, in East Africa Time (UTC+3).
  • Set a client timeout on every call; 30 seconds is plenty.
  • Retry 5xx responses at most three times, with exponential backoff.

Authentication

Create an access token

POST/v1/oauth/token

Exchanges your client credentials for a bearer token. Request a new token when the current one expires, not before every call.

Body

client_idstringRequired
Your client ID.
client_secretstringRequired
Your client secret.
grant_typestringRequired
Always client_credentials.

Returns (inside data)

access_tokenstringRequired
The bearer token.
token_typestringRequired
Always Bearer.
expires_inintegerRequired
Seconds until the token expires (72000, which is 20 hours).

Errors

HTTPerror.codeWhen
400invalid_requestclient_id or client_secret is missing.
400invalid_grantgrant_type is not client_credentials.
500invalid_clientThe client ID or secret is wrong, or the secret was regenerated.
POST /v1/oauth/token
curl --request POST "https://sandbox.zangupay.com/v1/oauth/token" \
  --max-time 30 \
  --header "Content-Type: application/json" \
  --data '{
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "grant_type": "client_credentials"
  }'
Response · 200
{
  "data": {
    "access_token": "bidx_3f9c2a…",
    "token_type": "Bearer",
    "expires_in": 72000
  }
}

Tenders

List tenders

GET/v1/connect/bid

Returns every tender, quotation and pre-qualification your organisation has created on BidX, including drafts.

Requires Authorization: Bearer with an access token.

  • Filter out status: "Creation" if you only want published tenders.

Returns (inside data)

idstringRequired
The tender's ID.
serial_nostringRequired
BidX serial number.
referencestringRequired
Your reference number.
descriptionstringRequired
The tender's title.
bid_typestringRequired
TENDER, QUOTATION or PRE-QUALIFICATION.
eligibilitystringRequired
OPEN-TO-ALL, BY-INVITATION or AGGREGATED-SUPPLIERS.
statusstringRequired
Lifecycle stage: Creation (draft), Submitted, Running, Evaluation, InReview, Frozen or Awarded.
expiresbooleanRequired
Whether it has a deadline.
expiry_date_timestringRequired
The deadline, in East Africa Time.
fee_per_categorynumberRequired
Fee to apply.
versionintegerRequired
Revision number.
slugstringRequired
URL-safe identifier.
timestampstringRequired
Created at, EAT.
projectobjectRequired
The owning organisation.

Errors

HTTPerror.codeWhen
401invalid_access_tokenNo token, or the token expired.
401invalid_access_token_formatThe Authorization header does not start with Bearer .
GET /v1/connect/bid
curl --request GET "https://sandbox.zangupay.com/v1/connect/bid" \
  --max-time 30 \
  --header "Authorization: Bearer $BIDX_ACCESS_TOKEN"
Response · 200
{
  "data": [
    {
      "id": "6aa79462460da1f202aa6464",
      "serial_no": "260911",
      "reference": "RFQ/ICT/2026/014",
      "description": "Supply of laptops and accessories",
      "bid_type": "QUOTATION",
      "eligibility": "OPEN-TO-ALL",
      "status": "Awarded",
      "expires": true,
      "expiry_date_time": "30-Sep-2026 07:07",
      "fee_per_category": 0,
      "version": 1,
      "slug": "supply-of-laptops-and-accessories-v7y4",
      "visibility": null,
      "timestamp": "14-Sep-2026 09:29",
      "project": {
        "id": null,
        "business_entity": {
          "id": "675bcad93ba6a684819d8974",
          "business_name": "Acme Holdings Ltd",
          "website": "www.example.com",
          "media": {
            "logo_url": "https://cdn.example.com/logo.png",
            "uploaded": true
          }
        }
      }
    }
  ]
}

Awarded suppliers

List awarded suppliers

GET/v1/connect/bid/{bid_id}/master-list

Returns the master list for a tender: every supplier awarded at least one category.

Requires Authorization: Bearer with an access token.

  • Returns at most 50 suppliers.
  • An empty data array means nothing is awarded yet.

Path parameters

bid_idstringRequired
The tender's id, as returned by List tenders.

Returns (inside data)

application_idstringRequired
The award's bid application.
scorenumberRequired
The application's evaluation score.
category_countintegerRequired
How many categories of the tender the supplier applied for.
business_entityobjectRequired
The supplier: business_entity_id, business_name, registration_number, registration_year, kra_pin, tcc_number, compliance_status, industry, country, town_city, physical_address, postal_code, website, applicant_name, email_address, phone_number, contacts, banks and owners.

Errors

HTTPerror.codeWhen
401invalid_access_tokenNo token, or the token expired.
401invalid_access_token_formatThe Authorization header does not start with Bearer .
GET /v1/connect/bid/{bid_id}/master-list
curl --request GET "https://sandbox.zangupay.com/v1/connect/bid/6aa79462460da1f202aa6464/master-list" \
  --max-time 30 \
  --header "Authorization: Bearer $BIDX_ACCESS_TOKEN"
Response · 200
{
  "data": [
    {
      "application_id": "6a0f5c2e9b1d4a7e3c8f2b61",
      "score": 87.5,
      "category_count": 2,
      "business_entity": {
        "business_entity_id": "65f1b2c3d4e5f60718293a4b",
        "business_name": "Savanna Office Supplies Ltd",
        "registration_number": "PVT-2019-004812",
        "registration_year": "2019",
        "kra_pin": "P051234567Z",
        "tcc_number": "KRATCC0012345",
        "compliance_status": "Compliant",
        "industry": "Office supplies",
        "country": "Kenya",
        "town_city": "Nairobi",
        "physical_address": "Mombasa Road, Nairobi",
        "postal_code": "00100",
        "website": "www.example.co.ke",
        "applicant_name": "Jane Wanjiru",
        "email_address": "tenders@example.co.ke",
        "phone_number": "+254700000000",
        "contacts": [],
        "banks": [],
        "owners": []
      }
    }
  ]
}

Awarded suppliers

Retrieve an awarded supplier

GET/v1/connect/bid/{bid_id}/master-list/{application_id}

Returns one entry of a tender's master list.

Requires Authorization: Bearer with an access token.

  • data is a list with one entry, or empty when that application was not awarded.

Path parameters

bid_idstringRequired
The tender's id, as returned by List tenders.
application_idstringRequired
The application_id from List awarded suppliers.

Returns (inside data)

application_idstringRequired
The award's bid application.
scorenumberRequired
The application's evaluation score.
category_countintegerRequired
How many categories of the tender the supplier applied for.
business_entityobjectRequired
The supplier: business_entity_id, business_name, registration_number, registration_year, kra_pin, tcc_number, compliance_status, industry, country, town_city, physical_address, postal_code, website, applicant_name, email_address, phone_number, contacts, banks and owners.

Errors

HTTPerror.codeWhen
401invalid_access_tokenNo token, or the token expired.
401invalid_access_token_formatThe Authorization header does not start with Bearer .
GET /v1/connect/bid/{bid_id}/master-list/{application_id}
curl --request GET "https://sandbox.zangupay.com/v1/connect/bid/6aa79462460da1f202aa6464/master-list/6a0f5c2e9b1d4a7e3c8f2b61" \
  --max-time 30 \
  --header "Authorization: Bearer $BIDX_ACCESS_TOKEN"
Response · 200
{
  "data": [
    {
      "application_id": "6a0f5c2e9b1d4a7e3c8f2b61",
      "score": 87.5,
      "category_count": 2,
      "business_entity": {
        "business_entity_id": "65f1b2c3d4e5f60718293a4b",
        "business_name": "Savanna Office Supplies Ltd",
        "registration_number": "PVT-2019-004812",
        "registration_year": "2019",
        "kra_pin": "P051234567Z",
        "tcc_number": "KRATCC0012345",
        "compliance_status": "Compliant",
        "industry": "Office supplies",
        "country": "Kenya",
        "town_city": "Nairobi",
        "physical_address": "Mombasa Road, Nairobi",
        "postal_code": "00100",
        "website": "www.example.co.ke",
        "applicant_name": "Jane Wanjiru",
        "email_address": "tenders@example.co.ke",
        "phone_number": "+254700000000",
        "contacts": [],
        "banks": [],
        "owners": []
      }
    }
  ]
}