SBCoreX · Integration Guide

Connect to the
SmartBamboo POS API

A single GraphQL endpoint for products, customers, orders, and payments — the same data the point-of-sale runs on. This guide gets you authenticated and reading the schema in a few minutes.

Protocol  GraphQL over HTTPS Transport  AWS AppSync Method  POST Encoding  application/json
POST /graphql
# every call is a POST with a query body
{ "query": "{ ping }" }
200 response
{
  "data": {
    "ping": "pong"
  }
}
01

Connect

The API lives behind one GraphQL endpoint. We hand you three values at onboarding — keep the key secret and out of client-side code.

ValueShapeWhat it's for
Endpoint URLhttps://<id>.appsync-api.<region>.amazonaws.com/graphqlWhere every request is POSTed.
API keysb-core-x-key-<env>Opens the public endpoints (login, ping). Sent as x-api-key.
Regionus-east-2The AWS region the endpoint runs in.
EnvironmentsTest against the dev endpoint first — it mirrors the schema exactly but runs on isolated data. You get a separate URL and key for production once integration is signed off.
02

Authenticate

Authentication is two-tier. The API key gets you to the public endpoints; logging in returns a short-lived JWT that unlocks everything else. Pick the header that matches what you're calling.

Primary

JWT token

Sent on every protected query and mutation. Obtained from login.

authorizationToken: <jwt>
Public

API key

For the open endpoints — login, ping, isTokenValid.

x-api-key: <key>
Internal

AWS IAM

SigV4-signed, reserved for our own service-to-service webhooks.

Authorization: AWS4-HMAC-…

Step 1 — Exchange credentials for a token

Call login with the API key in the header. It returns a JWT valid for roughly 24 hours, plus the signed-in user and company.

POST /graphql · x-api-key
mutation Login {
  login(
    serverUrl: "https://odoo.smartbamboo.mx"
    database:  "production"
    username:  "partner@example.com"
    password:  "••••••••"
  ) {
    token           # put this in authorizationToken
    user {
      id
      name
      email
      company { id name }
    }
  }
}

Step 2 — Send the token on protected calls

From here on, set authorizationToken to the JWT. The API key is no longer needed for these requests.

Step 3 — Refresh before it expires

Call refreshToken with a still-valid token to get a fresh one — no need to re-enter credentials.

POST /graphql · authorizationToken
mutation Refresh {
  refreshToken { token }
}
03

Make a request

Every call — query or mutation — is a single POST with a JSON body containing query and optional variables. Here's a complete authenticated request over curl.

POST curl
curl -X POST "$ENDPOINT" \
  -H "authorizationToken: $JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query Products($q: String!) { getProducts(search: $q) { id name listPrice } }",
    "variables": { "q": "almohada" }
  }'

A successful response wraps results under data, keyed by the operation name:

200 response
{
  "data": {
    "getProducts": [
      { "id": 5659, "name": "Almohada Memory", "listPrice": 499.00 }
    ]
  }
}
04

Explore live

Run real queries against the endpoint right here. Open the Headers tab in the explorer and add x-api-key (for public operations) or authorizationToken (for everything else), then hit run. The full schema loads by introspection once your headers are accepted.

Loading the GraphQL explorer… if this doesn't appear, your network may block the Apollo embed. Use the curl example above instead.

Powered by Apollo's embedded Explorer. Nothing you type here is stored on this page.

05

Schema

The API exposes queries for reading and mutations for writing. Below are the operations most external integrations use. The full schema is browsable in the explorer above and available on request.

Queries — read data

Query
getProducts(search): [Product]
Search the catalog by name or code.
Query
getProductCategories: [Category]
The category tree used to group products.
Query
searchPartners(search): [Partner]
Look up customers by name, phone, or tax id.
Query
getOrderById(id): Order
Fetch a single order with its lines and totals.
Query
searchOrders(filters): [Order]
Query orders by date, customer, or status.
Query
getCustomerHistory(partnerId): [Order]
A customer's purchase history.
Query
getPaymentMethods: [PaymentMethod]
Payment methods available to a point of sale.
Query
getQuotation(id): Quotation
Retrieve a saved quotation / wishlist.
Query
getHomeDeliveries(filters): [HomeDelivery]
Delivery orders and their fulfillment status.

Mutations — write data

Mutation
login(serverUrl, database, username, password): AuthResult
Authenticate and receive a JWT.
Mutation
refreshToken: AuthResult
Renew a valid token.
Mutation
createPartner(input): Partner
Register a new customer.
Mutation
updatePartner(id, input): Partner
Edit an existing customer.
Mutation
createOrderFromCart(cartId): Order
Turn a built-up cart into an order.
Mutation
saveWishlist(input): Quotation
Save a quotation for later checkout.
NoteCart-building (createCart, addItemToCart, …) and terminal payments exist too, but they're tuned for the live POS session. Talk to us before driving the checkout flow externally so we can scope the right operations.
06

Core types

The shapes you'll read most often. Fields shown are the common ones — request only what you need; GraphQL returns exactly the fields you select.

type Product · Partner · Order
type Product {
  id: Int!
  name: String!
  defaultCode: String      # internal reference / SKU
  barcode: String
  listPrice: Float
  qtyAvailable: Float      # store-scoped stock
  categ: Category
}

type Partner {
  id: Int!
  name: String!
  email: String
  phone: String
  vat: String             # tax id (RFC)
}

type Order {
  id: Int!
  reference: String        # pos reference
  partner: Partner
  dateOrder: String
  amountTotal: Float
  state: String            # draft · paid · done · invoiced
  lines: [OrderLine]
}

type OrderLine {
  productId: Int!
  productName: String
  qty: Float
  priceUnit: Float
  discount: Float
  priceSubtotalIncl: Float  # tax-inclusive subtotal
}

Field names follow GraphQL camelCase. Money is decimal Float; prices on order lines are tax-inclusive unless noted.

07

Errors

The HTTP status is almost always 200 — GraphQL reports problems in an errors array alongside (or instead of) data. Always check for errors before trusting data.

200 error envelope
{
  "errors": [
    { "message": "Not Authorized to access getProducts" }
  ]
}
Message containsCauseFix
Not AuthorizedMissing, expired, or wrong-tier token.Re-run login or refresh; confirm you're using authorizationToken.
UnauthorizedExceptionBad or absent x-api-key on a public call.Check the API key header and value.
field validation textBad arguments or input shape.Compare against the schema and types above.
08

REST endpoints legacy

A small REST surface exists for backward compatibility. Prefer GraphQL for new work — these routes will not gain features. Base URL: https://<id>.execute-api.<region>.amazonaws.com/<env>.

MethodPathPurpose
POST/auth/loginAuthenticate (use GraphQL login instead).
GET/partnersSearch customers.
POST/partnersCreate a customer.
PUT/partners/{id}Update a customer.
GET/productsSearch products.
GET/pricelistsList pricelists.