Tote developers
All guides

Basics

Getting started

What the Tote API is, how requests are shaped, and the conventions every endpoint shares.

The Tote API serves three mobile apps — customer, driver and merchant — from one versioned JSON surface. Every endpoint lives under /api/v1.

These guides explain the concepts behind the endpoints. The API reference is generated from the code and lists every endpoint with its exact request and response schema. Read a guide to understand a flow, then use the reference for field-level detail.

Making a request#

Send every request with these headers:

Accept: application/json
Content-Type: application/json
Authorization: Bearer <token>
  • Accept: application/json is required. Without it, a validation error or a missing token can come back as a redirect instead of a JSON error.
  • Authorization is needed on every endpoint except registration, login and a few public Platform · … endpoints. See Authentication & audiences.
  • Uploads (photos, documents) are multipart/form-data; arrays use bracket names, for example photos[] or lines[0][quantity].

Audiences#

Endpoints are grouped by the app that calls them. The group name in the API reference starts with the audience:

Group prefix Audience URL prefix
Platform · … Shared or public /api/v1/init, /api/v1/product-category, …
Customers · … Customer app /api/v1/customers/auth/…
Drivers · … Driver app /api/v1/drivers/auth/…
Merchants · … Merchant app /api/v1/merchants/auth/…

The …/auth/ prefix holds all of an audience's routes, not only login: profile, orders and stores live under it too.

Localization#

Pass ?lang=ar or ?lang=en on any request to pick the language of messages and labels. Any other value is ignored and the app's default locale applies.

Translatable content — store and product names, category titles, offer descriptions — is returned as an object keyed by locale, whatever lang is:

{ "name": { "ar": "أسواق النور", "en": "Al Noor Market" } }

Pick the key that matches the device language on the client.

Money#

Prices and amounts are decimal SAR numbers, for example 139.5. There is no other currency.

Errors#

Status Meaning Body
401 No token, a revoked token, or a token from another audience {"message": "Unauthenticated."}
403 Authenticated but not allowed: someone else's record, a deleted or inactive account {"message": "…"}
404 The record does not exist, or belongs to a store you cannot see {"message": "…"}
422 Validation failed, or the action is not possible in the current state {"message": "…", "errors": {"field": ["…"]}}
429 Too many requests on a throttled endpoint {"message": "Too Many Attempts."}

Messages are translated according to lang, so show message to the user as-is rather than mapping status codes to your own copy.

Lists and pagination#

List endpoints return a Laravel paginator: the rows are in data, with current_page, last_page, per_page, total and next_page_url beside them. Ask for the next page with ?page=2. Some endpoints nest the paginator under a named key (for example returns); the reference shows which.

Demo accounts#

On local and staging, the overview page of the API reference lists seeded customer, driver and merchant accounts you can log in with. They never appear on production.

Known quirks#

Inconsistencies the API keeps for now, because the apps already depend on them (see the Changelog):

  • Driver token key. Driver register returns the token as access_token; driver login returns it as token. Customer and merchant use access_token for both.
  • Password rules differ. Customer and merchant registration need 8 characters. Driver registration, converting a guest, creating staff and changing a password need upper and lower case letters, a number and a symbol instead. Validate on the device with the rule of the endpoint you call.
  • Response envelopes vary. Many endpoints wrap results as {"status": "success", …} with the data under a named key (orders, stores, data); authentication endpoints return their fields at the top level. Read the key the API reference shows for each endpoint.
  • Two routes list customer addresses. profile/addresses and profile/address/es return the same list. Use profile/addresses.
  • Push language. Push titles and bodies use the platform's default language, not the device's; see Push notifications.