Server-to-Server

Account S2S Integration

Server-to-server integration for account systems over REST and WebSocket.

The integration surface is production-ready. Build on top of api.niyantha.in using this guide as the stable contract for your backend integration.

RESThttps://api.niyantha.in
WSwss://api.niyantha.in/ws

Authentication

API Keys

  • Keys are issued per account and required for S2S REST + WS.
  • Default expiry is 24 hours. Override with ttl_seconds (relative) or expires_at (absolute Unix seconds).
  • Expired or revoked keys are rejected immediately.

REST Authentication

Use either approach:

Option A — Headers

X-API-Key: <public_key>
X-API-Secret: <secret>

Option B — HTTP Basic Auth

username = <public_key>
password = <secret>

WebSocket Authentication

Connect to wss://api.niyantha.in/ws and send auth.login with authType: "s2s":

Request
{
  "type": "auth.login",
  "requestId": "s2s-auth-1",
  "payload": {
    "authType": "s2s",
    "token": "<public_key>",
    "metadata": {
      "secret": "<secret>",
      "app": "anystore",
      "storeId": "<optional>"
    }
  }
}
Response
{
  "type": "auth.success",
  "requestId": "s2s-auth-1",
  "payload": {
    "identityId": "account-<accountId>",
    "role": "account",
    "context": { "accountId": "<id>" }
  }
}

Key Management (REST + WS)

Key management uses account session auth (Authorization: Bearer <token>). These endpoints are not S2S-key protected.

REST

POST
/api/v1/session/keys

Create a new API key

Request Body
{ "name": "primary", "ttl_seconds": 86400 }
Response
{
  "id": 10,
  "name": "primary",
  "username": "<public_key>",
  "secret": "<secret>",
  "expires_at": 1739580000
}
GET
/api/v1/session/keys

List all API keys

Response
{
  "items": [
    {
      "id": 10,
      "name": "primary",
      "username": "<public_key>",
      "created_at": 1739493600,
      "expires_at": 1739580000,
      "revoked_at": 0,
      "last_used_at": 1739497200
    }
  ]
}
PATCH
/api/v1/session/keys/:id/expire

Revoke / expire a key

Response: key summary (same shape as list item)

WebSocket

WS
account.keys.create

Payload: { name, ttl_seconds } → account.keys.create.ok with { id, name, username, secret, expires_at }

WS
account.keys.list

Payload: {} → account.keys.list.ok with { items: [...] }

WS
account.keys.expire

Payload: { key_id } → account.keys.expire.ok with key summary

Sample Payload Cookbook

Create Store

POST /api/v1/s2s/accounts/stores
{
  "type": "grocery",
  "name": "Fresh Mart Hub",
  "description": "Neighborhood store connected to Niyantha logistics",
  "location_id": 101,
  "owner_aadhaar_front_file_id": 12,
  "owner_aadhaar_back_file_id": 13,
  "shop_body_type": "stationary_shop"
}

Create Store Product

POST /api/v1/s2s/accounts/stores/:id/products
{
  "store_item_id": 501,
  "name": "Tomato Crate",
  "type": "vegetable",
  "unit": "kg",
  "price_per_unit": 24,
  "min_order_unit": 1,
  "max_order_unit": 100,
  "stock_type": "limited",
  "stock": 400
}

Create Shipment

POST /api/v1/s2s/accounts/shipments
{
  "from_location_id": 101,
  "to_location_id": 205,
  "vehicle_type": "truck",
  "load_weight": 1250,
  "notes": "Handle with care"
}

Driver Location Update

POST /api/v1/s2s/accounts/drivers/location
{
  "latitude": 12.9716,
  "longitude": 77.5946,
  "measured_at": 1736768400,
  "accuracy": 9
}

S2S REST Endpoints

Base path: https://api.niyantha.in/api/v1/s2s/accounts — API key auth required on all endpoints.

Account Profile

GET
/

Get account profile

POST
/update

Update profile

POST
/update_password

Update password

POST
/initiate_contact_update

Start contact update flow

POST
/update_contact

Confirm contact update

POST
/initiate_email_update

Start email update flow

POST
/update_email

Confirm email update

Account Apps

GET
/apps

List apps

POST
/apps

Create app

POST
/apps/logo

Upload app logo

GET
/apps/:id

Get app

POST
/apps/:id

Update app

GET
/apps/settings

App settings bootstrap

Stores

GET
/stores

List stores

GET
/stores/:id

Get store

POST
/stores

Create store

POST
/stores/:id

Update store

GET
/stores/:id/settings

Store settings

Store Products

POST
/stores/:id/products

Create store product

GET
/stores/:id/products

List store products

GET
/stores/:id/products/:product_id

Get store product

PATCH
/stores/:id/products/:product_id

Update store product

DELETE
/stores/:id/products/:product_id

Delete store product

Base Products (read-only)

GET
/base-products

List base products

Catalog Products

POST
/products

Create catalog product

PUT
/products/:id

Update catalog product

GET
/products/:id

Get catalog product

GET
/products

List catalog products

Orders

GET
/orders

List orders

GET
/orders/:id

Get order

POST
/orders/:id/accept

Accept order

POST
/orders/:id/decline

Decline order

PATCH
/orders/:id/mark-paid-and-delivered

Mark paid and delivered

GET
/stores/:store_id/orders

List store orders

Locations

POST
/locations/estimate

Estimate distance/time

POST
/locations/address/coordinates

Geocode address

POST
/locations/coordinates/address

Reverse geocode

POST
/locations

Create location

GET
/locations

List locations

GET
/locations/:id

Get location

POST
/locations/:id

Update location

Files

POST
/files

Upload file (multipart)

GET
/files/:id

Get file

Networks

POST
/networks

Create network

GET
/networks

List networks

GET
/networks/:id

Get network

Shipments

POST
/shipments

Create shipment

GET
/shipments

List shipments

GET
/shipments/:id

Get shipment

AI Characters

GET
/stores/:store_id/characters

List store AI characters

POST
/stores/:store_id/characters

Create store AI character

PATCH
/characters/:character_id

Patch AI character

GET
/characters

List account AI characters

Drivers

GET
/drivers

Get driver profile

POST
/drivers/update-licenses

Update driver licenses

POST
/drivers/location

Report driver location

GET
/drivers/shipments

List assigned shipments

POST
/drivers/shipments/:id/accept

Accept assigned shipment

POST
/drivers/shipments/:id/reject

Reject assigned shipment

PUT
/drivers/shipments/:id/complete

Complete shipment

Wallet

GET
/wallet

Get wallet

POST
/wallet

Create wallet

AFA Parity

POST
/afas

Create AFA / OTP flow for S2S parity use cases

S2S WebSocket APIs

Connect to wss://api.niyantha.in/ws and authenticate with auth.login using authType: "s2s". After auth.success, use the same message types as the normal account WS API.

Account Profile

WS
account.get
WS
account.update
WS
account.logout

Stores

WS
store.create
WS
store.fetch
WS
store.get
WS
store.update
WS
store.status.update
WS
store.attach
WS
account.stores.fetch
WS
account.store.get

Products

WS
product.create
WS
product.update
WS
product.get
WS
product.list
WS
account.store.products.create
WS
account.store.products.list
WS
account.store.products.get
WS
account.store.products.update

Orders

WS
account.orders.fetch
WS
account.store.orders.fetch
WS
account.order.get
WS
account.store.order.get
WS
order.accept
WS
order.reject
WS
order.preparing
WS
order.prepared
WS
order.picked
WS
order.delivered

Locations

WS
location.create
WS
location.fetch
WS
location.search
WS
location.get
WS
location.update
WS
account.location.estimate
WS
account.location.address.coordinates
WS
account.location.coordinates.address

Files

WS
account.files.create
WS
account.files.get
WS
file.stream.start
WS
file.stream.complete

Reviews

WS
account.reviews.create
WS
account.reviews.update
WS
account.reviews.list
WS
account.reviews.get
WS
account.review.replies.list
WS
account.review.like.add
WS
account.review.like.remove
WS
store.reviews.list
WS
store.reviews.get
WS
store.review.replies.list

Networks

WS
account.network.create
WS
account.network.update
WS
account.network.fetch
WS
account.network.get
WS
account.network.vehicle.request
WS
account.network.vehicle.request.review
WS
account.network.vehicle.attach
WS
account.network.vehicles.list

Vehicles

WS
account.vehicle.create
WS
account.vehicle.get
WS
account.vehicle.fetch

Shipments

WS
account.shipment.create
WS
account.shipment.fetch
WS
account.shipment.get

AI Characters

WS
ai.threads.list
WS
ai.threads.create
WS
ai.threads.get
WS
ai.thread.send
WS
ai.thread.send.stream
WS
nitha.thread.send.stream

Drivers

WS
account.driver.shipments.pending.fetch

Notes

  • 1S2S keys are scoped to an account and inherit store ownership checks.
  • 2If you include metadata.storeId during WS auth, the socket also attaches that store identity when it exists and belongs to the account.
  • 3Expiring a key immediately revokes access for both REST and WS.
  • 4The integration surface is a stable, production contract. Platform updates are auto-deployed without breaking existing API clients.

Need Help Launching on Niyantha?

Build on api.niyantha.in using this guide as the production contract for your backend integration.