Open Application Platform Docs

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

GraphQL

271 operations at /app/graphql, in their own schema.

GraphQL reference · Specification

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.

JavaScriptsr.callOperation(operation, params)
DartcallOperation(Operation operation, Map<String, Object?> params, {body, files})
SwiftcallOperation(_ operation: Operation, params:, body:, files:) async throws -> JSON
Kotlinsuspend fun callOperation(operation: Operation, params, body, files): JsonElement
C#CallOperationAsync(Operation operation, parameters, body, files, cancellationToken)
Pythoncall_operation(operation, params=None, body=None, files=None)
PHPcallOperation(Operation $operation, array $params = [], ?array $body = null, array $files = [])
GoCallOperation(ctx, op Operation, params, body map[string]any, files []File, opts ...CallOption)
JavacallOperation(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}