Skip to main content

Operation tokens for your mobile app

Let users of your own app open and close products over Bluetooth, even where the site has no network. Your backend creates a short-lived operation token for one product; your app hands it to the product through the Parklio SDK. This guide covers the backend side in full, and the app side as a flow.

Prerequisites​

  • An API token, on your backend only; see Authentication. Never ship it in the app.
  • Products paired with your account. A Gateway isn't needed for this path.
  • Access to the Parklio SDK for your app (Android, iOS): it's shared under contract. Contact info@parklio.com. See SDK.

The flow​

  1. A user asks your app for access to a product, for example when their booking starts.
  2. Your app asks your backend, which checks the user is allowed.
  3. Your backend creates an operation token for that product and a short window, and returns it to the app.
  4. The app, through the SDK, sends the token's open or close command to the product over Bluetooth. The product checks the signature and the window itself; no network is needed at the product.
  5. When the window ends, the token stops working.

1. Create a token, just in time​

Call POST /v2/operation-tokens with the product and a window. Times are ISO-8601 in UTC.

Create an operation token
curl -s -X POST https://api.parklio.com/v2/operation-tokens \
-H "Authorization: Bearer $PARKLIO_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"product_id": 123,
"start_time": "2026-03-02T08:00:00.000Z",
"end_time": "2026-03-02T10:00:00.000Z"
}'

The response (HTTP 200):

Response
{
"success": true,
"data": {
"id": 9001,
"product_id": 123,
"start_time": "2026-03-02T08:00:00.000Z",
"end_time": "2026-03-02T10:00:00.000Z",
"status": "active",
"used_count": 0,
"is_unlimited": 0,
"token_open": { "token": "<hex>", "status_key": "<hex>", "challenge_key": "<hex>" },
"token_close": { "token": "<hex>", "status_key": "<hex>", "challenge_key": "<hex>" },
"token_status": { "token": "<hex>", "status_key": "<hex>", "challenge_key": "<hex>" },
"product": { "id": 123, "device_id": "B1234567" },
"created_at": "2026-03-02T07:59:58.000Z",
"updated_at": "2026-03-02T07:59:58.000Z"
}
}

Return token_open, token_close and token_status, unchanged, plus the product's device_id and end_time, to your app. The SDK documentation explains how the app uses them.

2. Keep windows short​

Revoking a token doesn't reach the device. The window is signed into the token, and the product checks it on its own. Blocking a token (PATCH /v2/operation-tokens/{id} with {"status": "blocked"}) or deleting it only changes Parklio's records; a copy the app already holds keeps working until end_time.

So the window is your revocation:

  • Create tokens when the user needs access, not in advance.
  • Make the window as short as your use case allows: the length of a booking, or a few minutes for a single "open now".
  • Create a new token to extend access; a token can't be changed.
  • Don't use "is_unlimited": true. It sets end_time to 2038-01-01, and such a token can never be revoked on the device.
  • start_time may be in the past; end_time must be in the future.

3. Store nothing long-lived​

  • Don't keep tokens in your database once delivered, and don't let the app cache them beyond end_time. Create a new one each time.
  • Keep the API token on your backend. The app should only ever see operation tokens.
  • Use HTTPS between your app and backend, and authenticate the user before you create a token for them: whoever holds a token can operate the product until it expires.

4. Check the device clock​

Time windows need the product's clock to be set. If a product reports product_error.rtcc_invalid = 1 (see Monitor devices), its clock isn't set and time-limited tokens fail until it is. Parklio sets the clock when a Gateway sees the product; on a site with no Gateway, contact support.

What the API tracks, and what it doesn't​

  • status becomes expired (checked hourly) after end_time, blocked after you block it, and invalid when the product is removed from its lot or paired again.
  • used_count doesn't count uses over Bluetooth: the product doesn't report them to Parklio. Log opens in your app if you need them.
  • GET /v2/operation-tokens lists tokens, filterable by product_id and status.
  • Operation tokens need no plan feature and no Gateway.

Verify it worked​

  1. POST /v2/operation-tokens returns status: "active" and the three commands.
  2. Your app, near the product, sends token_open: the product opens (on a barrier, the arm lowers).
  3. After end_time, the same command is refused by the product.

Common errors​

HTTPCodeCauseFix
403402Neither end_time nor is_unlimited.Send an end_time.
403403end_time is in the past.Use a future end_time.
403405end_time is before start_time.Fix the window.
403404A time after 2038.Use an earlier time.
403206The product isn't paired.Pair it with the Connect app.
4046No such product, or your token can't see it.Check the id and the product's lot.
——The product refuses the token.Check the window, the device clock (rtcc_invalid), and that the product wasn't paired again since the token was created.

Next​