Partner app API
The REST and GraphQL surface sApp calls: one method per operation.
REST
308 operations under /app/v1. Calls before sign-in use an app key; calls after sign-in use the person's token.
REST reference · Specification OpenAPI 3.1
The SDK methods are generated from these specifications, so every operation has a method on every platform.
The smart-locker operations (pickups, locker locations, locker storage, the locker shop and second-hand handover) are part of the API and of these references. In the SDKs they are called through sLocker. sLocker
| Category | Operations |
|---|---|
| Account | 20 |
| Wallet | 6 |
| Orders | 12 |
| Lockers | 36 |
| Store | 34 |
| Group buy | 17 |
| Public | 59 |
| Customer orders | 38 |
| Driver | 49 |
App capabilities
An app asks for capabilities when it is registered. Sensitive capabilities are approved only while the account holds the matching permission from Superroute.
app.develop |
Register apps. |
app.wallet_top_up |
Top up the wallet. |
app.pay_scan |
Scan to pay. |
app.locker_remote_open |
Open a locker door remotely. |
app.locker_shop |
Buy from the locker shop. |
app.locker_resale |
Hand items over through a locker. |
app.password_sign_in |
Sign in with email and password in the app's own screens. |
app.driver_cash |
Record cash collected by drivers. |
app.driver_claim |
Take orders from the order pool and the route board. |
app.driver_route_edit |
Add orders to a route and take them off. |
Building on the sApp core
callOperation calls an operation that the package does not generate, from a description written by hand: method, path, authentication, query names, header parameters and body kind. The call takes the same path as a generated method: the token or app key, one refresh and resend after a 401, idempotency keys, retries and errors. It is for packages built on the sApp core, such as sLocker.
| JavaScript | sr.callOperation(operation, params) |
| Dart | callOperation(Operation operation, Map<String, Object?> params, {body, files}) |
| Swift | callOperation(_ operation: Operation, params:, body:, files:) async throws -> JSON |
| Kotlin | suspend fun callOperation(operation: Operation, params, body, files): JsonElement |
| C# | CallOperationAsync(Operation operation, parameters, body, files, cancellationToken) |
| Python | call_operation(operation, params=None, body=None, files=None) |
| PHP | callOperation(Operation $operation, array $params = [], ?array $body = null, array $files = []) |
| Go | CallOperation(ctx, op Operation, params, body map[string]any, files []File, opts ...CallOption) |
| Java | callOperation(Operation operation, Map<String, Object> params, Map<String, ?> body, List<OperationFile> files) |
const answer = await sr.callOperation(
{ method: 'POST', path: '/app/v1/things/{id}/open', auth: 'token', query: [], body: 'json',
headers: { 'Idempotency-Key': 'idempotencyKey' } },
{ id: 42, body: { note: 'at the door' } },
);
The server still decides what the caller may do: an operation described by hand reaches nothing that a generated method could not reach.
Errors and retries
Every failed call raises one error type with the HTTP status, the server's code and the parsed body; signInRequired is true when the person must sign in again. Repeatable calls are retried on a lost connection and on temporary server errors; writes are never retried.
The error also carries the response headers, the request id and, when the answer has a Retry-After header, the seconds to wait before trying again.
GET /app/v1/health
GET /app/v1/me
POST /app/graphql
Calls without signing in
These operations take the app key alone: the service provider's quote form and a price for one quote line, its smart lockers and pickup point counters near a position or by search, the settings of an sWidget by its key, and a widget the service provider enabled for the app, by its id.
GET /app/v1/clients/{clientCode}/guest/quotes/schema
POST /app/v1/clients/{clientCode}/guest/quotes/{line}
GET /app/v1/clients/{clientCode}/guest/pickup-points
GET /app/v1/clients/{clientCode}/swidget
GET /app/v1/clients/{clientCode}/swidgets/{widgetId}