Skip to content

Platform — Clients and projects ​

A platform team that opens projects on behalf of its clients uses this API to register a client, show the client's verification link in its own onboarding, open projects, take them live and set their payout account. Everything the Clients menu of the dashboard does is available here.

Platform mode

Platform mode is switched on for your team by the Byl team. Without it these endpoints return 404. Write to [email protected].

Team token ​

These endpoints take a team token, not a project token: create one under the account-level API tokens menu (visible to the team owner). A team token is also valid on the project endpoints of every project of the team, yours and your clients', so one token is enough to create checkouts and invoices in a client's project. See API token.

Authorization: Bearer <team token>

A project token or a legacy token returns 403.

The Client object ​

FieldTypeDescription
idNumberThe client's (business) ID. The business_id of webhook payloads.
client_reference_idStringYour own ID for the client.
nameStringBusiness name, copied from TrustAPI once verified; null before.
typeStringBusiness type (person, company …), once verified.
contact_emailStringWhere the verification link is sent.
phoneStringPhone, once verified.
statusStringOnboarding status, see below.
is_verifiedBooleanEvery step done: the client's projects can go live.
verified_atDateWhen that happened.
verification_statusStringStatus of the current TrustAPI attempt (pending, submitted, under_review, verified, rejected, expired).
stepsArraytrustapi, qpay, bank, each with status (pending, in_progress, done, error) and error.
qpay_merchant_idStringThe QPay merchant created for the client.
bank_accountsArrayActive bank accounts (id, bank_code, bank_name, account_number, account_name).
projectsArrayProjects opened for the client (id, name, mode). Retrieve only.
verificationObjecturl, expires_at and emailed of the attempt just started. Only in the create and verification-link responses.
created_atDateWhen the client was registered.

Onboarding status ​

statusMeaning
not_startedThe client has not opened its link and submitted anything.
in_reviewFilling in or submitted, awaiting a decision.
incompleteVerified by TrustAPI; the QPay merchant and bank account are being set up.
verifiedEvery step done.
rejectedRejected. Sending the link again starts a new attempt.
expiredThe link expired. Send it again.

Create a client ​

POST /v1/clients
ParameterTypeRequiredDescription
emailStringtrueThe client's email. The verification link goes there.
client_reference_idStringfalseYour own ID for the client. Up to 48 characters, unique per team.

The client is created, its verification starts on TrustAPI and the link is emailed. verification.url in the response is that link: show it in your own onboarding page. A second client with the same email or client_reference_id is refused (422).

If the verification service does not answer

The client is still created, with verification set to null. Wait a moment and start it with the verification link request.

Example request

shell
BYL_TEAM_TOKEN="your team token"

curl -X POST https://byl.mn/api/v1/clients \
    -H "Authorization: Bearer $BYL_TEAM_TOKEN" \
    -H 'Accept: application/json' \
    -H 'Content-Type: application/json' \
    -d '{
          "email": "[email protected]",
          "client_reference_id": "shop_42"
      }'

Example response

json
{
  "data": {
    "id": 118,
    "client_reference_id": "shop_42",
    "name": null,
    "type": null,
    "contact_email": "[email protected]",
    "phone": null,
    "status": "in_review",
    "is_verified": false,
    "verified_at": null,
    "verification_status": "pending",
    "steps": [
      { "key": "trustapi", "status": "in_progress", "error": null },
      { "key": "qpay", "status": "pending", "error": null },
      { "key": "bank", "status": "pending", "error": null }
    ],
    "qpay_merchant_id": null,
    "bank_accounts": [],
    "verification": {
      "url": "https://trustapi.dotly.mn/verify/tok_8f2a…",
      "expires_at": "2026-11-04T09:00:00+08:00",
      "emailed": true
    },
    "created_at": "2026-10-28T09:00:00.000000Z",
    "updated_at": "2026-10-28T09:00:00.000000Z"
  }
}

Retrieve a client ​

GET /v1/clients/:client_id
GET /v1/clients/by-client-reference-id/:client_reference_id

The response includes the client's projects. Each retrieve re-checks the status with TrustAPI, so it is right even when a webhook was missed. Another team's client returns 404.

shell
curl https://byl.mn/api/v1/clients/by-client-reference-id/shop_42 \
    -H "Authorization: Bearer $BYL_TEAM_TOKEN" \
    -H 'Accept: application/json'

List clients ​

GET /v1/clients
ParameterTypeDescription
statusStringFilter by onboarding status.
per_pageNumberPage size (default 25, at most 100).

Newest first, paginated (meta.total, links.next).

POST /v1/clients/:client_id/verification-link

When the client lost its link, the link expired or the attempt was rejected, this creates a (new) link and emails it; the response carries verification.url. It is refused with 409 when:

errorMeaning
already_verifiedThe client is already verified.
in_reviewSubmitted and awaiting a decision: nothing is left to fill in.
onboarding_in_progressVerified by TrustAPI; the remaining steps are completing automatically.

When the verification service does not answer: 503 verification_unavailable.

The Project object ​

FieldTypeDescription
idNumberProject ID, used on the project endpoints.
nameStringName.
modeStringTest or Live.
business_idNumberThe client the project runs under. null for the team's own projects.
emailStringThe project's contact email.
qpay_merchant_idStringThe QPay merchant linked to the project; linked automatically once the client is verified.
payout_bank_accountObjectThe account the project pays out to (id, bank_code, bank_name, account_number, account_name, is_active), or null.
created_atDateCreated at.

Create a project ​

POST /v1/projects
ParameterTypeRequiredDescription
nameStringtrueProject name. Up to 255 characters.
business_idNumberfalseThe client's id. Omit for a project under your own business.

A verified client's QPay merchant is linked to the new project right away; otherwise it is linked once the client is verified. A team without a plan can have one project (422 subscription_required); at the plan's limit, 422 project_limit_reached.

shell
curl -X POST https://byl.mn/api/v1/projects \
    -H "Authorization: Bearer $BYL_TEAM_TOKEN" \
    -H 'Accept: application/json' \
    -H 'Content-Type: application/json' \
    -d '{ "name": "Shop 42", "business_id": 118 }'
json
{
  "data": {
    "id": 57,
    "name": "Shop 42",
    "mode": "Test",
    "business_id": 118,
    "email": "[email protected]",
    "qpay_merchant_id": null,
    "payout_bank_account": null,
    "created_at": "2026-10-28T09:05:00.000000Z",
    "updated_at": "2026-10-28T09:05:00.000000Z"
  }
}

Retrieve and list projects ​

GET /v1/projects/:project_id
GET /v1/projects

The list returns every project of the team (yours and your clients'), newest first; business_id narrows it to one client. per_page as above.

Payout account ​

GET /v1/projects/:project_id/bank-accounts
PUT /v1/projects/:project_id/bank-account

GET lists the active accounts of the business the project runs under (the client's); the account the client gave TrustAPI is added automatically when it is verified. PUT with bank_account_id makes one of them the project's payout account; another business's account is refused with 422. A payout account is required before going live.

Switch the mode ​

PUT /v1/projects/:project_id/mode
ParameterTypeRequiredDescription
modeStringtrueTest or Live.

Going live needs a verified business, an active plan on the team and a payout account on the project; the error of the 422 names what is missing: business_not_verified, subscription_required, payout_account_required. The current mode is accepted as a no-op 200.

Working in a client's project ​

Once a project is open, call its checkout, invoice and customer endpoints with the same team token, with the returned id as :project_id. To receive the events of every project in one place, register a team webhook endpoint: the business_id of each payload tells which client it belongs to.

Next steps ​

  • API token — creating a team token
  • Webhook — team endpoints and business_id
  • Checkout — taking payments in a client's project