CloudPOS

CloudPOS REST API v2

One consistent, secured REST API for every CloudPOS installation. Read and manage customers, suppliers, billers, products, categories, warehouses, tax rates and more, and read sales, purchases, stock, payments and expenses — with the same permissions each user has in the admin panel.

OpenAPI 3.0API key + Bearer tokenHTTPS only Rate limitedAutomatic IP blocking2FA aware Download openapi.json

Quick start

1Create an API key

In your CloudPOS admin open Settings → API keys and create a key (optionally restrict it to your server’s IP address and a warehouse). Make sure API is enabled in system settings.

2Get a bearer token

Send the key plus your normal CloudPOS username and password to POST /api/v2/auth/token. You receive an access token (1 hour) and a refresh token (14 days).

3Call the API

Send both api-key and Authorization: Bearer <token> on every request. Without both you get 401.

# 1) get a token (api-key only)
curl -X POST https://YOUR-HOST/api/v2/auth/token \
  -H "api-key: YOUR_API_KEY" -H "Content-Type: application/json" \
  -d '{"username":"owner","password":"your-password"}'

# 2) use it (api-key AND bearer)
curl "https://YOUR-HOST/api/v2/customers?per_page=10&q=ali" \
  -H "api-key: YOUR_API_KEY" -H "Authorization: Bearer cp2_xxxxxxxx"

# 3) create / update / delete
curl -X POST   https://YOUR-HOST/api/v2/customers     -H "api-key: ..." -H "Authorization: Bearer ..." -H "Content-Type: application/json" -d '{"name":"Ali Traders","phone":"0300-1234567"}'
curl -X PATCH  https://YOUR-HOST/api/v2/customers/42  -H "api-key: ..." -H "Authorization: Bearer ..." -H "Content-Type: application/json" -d '{"city":"Lahore"}'
curl -X DELETE https://YOUR-HOST/api/v2/customers/42  -H "api-key: ..." -H "Authorization: Bearer ..."

Replace YOUR-HOST with your CloudPOS address (for example https://yourshop.cloudpos.pk). Every installation has its own API at /api/v2.

Test it on this page

The console below calls your CloudPOS server straight from your browser. Nothing is sent to cloudpos.pk, the password and tokens live only in this tab’s memory and are never stored.

Browsers may only call your server if it allows this site as an origin. CloudPOS allows https://cloudpos.pk by default. Use a real HTTPS address; use a test user, not your owner account, when demonstrating to others.
no token

idle
—

Security model

ProtectionHow it works
Two credentialsThe API key identifies the application; the bearer token identifies the logged-in CloudPOS user. Both are required on every call. A token only works together with the key it was issued for.
Passwords & tokensTokens are random 256-bit values and only their SHA-256 hash is stored. Changing the user’s password, disabling the user or logging out invalidates tokens immediately. Refresh tokens rotate on every use; replaying an old one revokes the whole session.
Login lockout5 wrong passwords from one IP in 10 minutes lock that IP out of login (429 login_locked with the seconds to wait). 20 wrong passwords against one account from any IPs pause API login for that account.
Automatic IP blockingBad API keys, bad tokens, bad logins and rate-limit abuse are strikes. 10 strikes in 15 minutes block the IP (403 ip_blocked): 15 min, then 1 h, 6 h, 24 h for repeat offenders. Owners can also set a per-key IP allow-list and a global allow-list.
Rate limits120 requests/min per IP, 300/min per token, 60 writes/min per token, 10 token requests/min per IP. Responses carry X-RateLimit-Limit, X-RateLimit-Remaining and Retry-After.
AuthorizationThe user’s group permissions apply exactly as in the admin panel (Admin accounts cannot delete, as in the panel). Warehouse, biller and “own records only” restrictions are enforced; a warehouse-bound API key limits data to that warehouse.
Input hardeningOnly whitelisted columns can be written (ids, group, balances and other system columns are read-only; unknown fields are rejected with 422), all queries are parameterised, filters and sort columns are whitelisted, bodies are limited to 1 MB JSON.
Transport & headersHTTPS required, strict CORS allow-list (no cookies are ever used), Cache-Control: no-store, nosniff, HSTS and a locked-down CSP on every response. No stack traces or SQL errors are ever returned.
2FAAccounts with authenticator-app 2FA send the 6-digit code (or a recovery code) as otp. Accounts using e-mailed one-time codes cannot use the API until authenticator 2FA is set up. Codes cannot be replayed.
Audit trailEvery request is logged (time, IP, key, user, method, path, status, duration — never passwords, tokens or bodies).

Conventions

  • Success: {"success":true,"data":...,"meta":{"page","per_page","total","pages"}}. Error: {"success":false,"error":{"code","message","retry_after?"}}.
  • Lists: page, per_page (max 100), q (search), sort=-id, fields=id,name, expand=items. Filter any column with ?city=Lahore or ?grand_total__gte=1000 (__ne __gt __gte __lt __lte __like __in __null).
  • GET /api/v2/<resource>/_schema returns the live columns of your installation: type, nullable, writable, required.
  • PUT is an alias of PATCH (partial update). POST returns 201 and a Location header.
  • Records that other documents depend on answer 409 in_use on delete (for example a customer with sales).
  • Sales, purchases, quotes, transfers, adjustments, payments, expenses, deposits and stock are read-only in v2: they must pass through the accounting engine (stock, costing and ledger) and are posted from the POS/admin or the v1 mobile APIs.

Status and error codes

HTTPcodeMeaning
400https_required, bad_json, unknown_filter, bad_idMalformed request
401invalid_api_key, token_required, invalid_token, invalid_credentials, otp_required, invalid_otp, invalid_refresh_tokenMissing or wrong credentials
403forbidden, ip_blocked, ip_not_allowed, not_allowed, two_factor_unsupportedAuthenticated but not allowed / IP blocked
404 / 405 / 409not_found, method_not_allowed, in_useUnknown record or method; delete blocked
413 / 415 / 422payload_too_large, unsupported_media_type, unknown_fields, read_only_fields, missing_fields, invalid_fieldBody rejected
429rate_limited, login_lockedSlow down; see Retry-After
503api_disabledAPI feature switched off for the account

Endpoint reference

Loading the OpenAPI specification…

Import cloudpos-openapi-v2.json into Postman, Insomnia, Swagger Editor or any OpenAPI code generator. Your own installation also serves it live (with your exact columns) at /api/v2/openapi.json.

WhatsApp Us