AWRA OpsHub Search

No Route Here Asks Who You Are Asking About

The public interface has one property that decides most of its security: no route accepts an organisation identifier from the caller. The key carries it, so there is nothing for a client to get wrong or to change.

Integrations & Data AWRA OpsHub Team 11 min read

The most dangerous parameter an interface can accept is the one naming whose data you want.

An interface serving many organisations has to answer two questions on every request: who is asking, and whose records they may see. Those can be one question or two, and choosing to make them one removes an entire class of failure.

The key is the organisation

A key is minted inside a workspace and belongs to it. Every request authenticated by that key is scoped to that workspace, and no route accepts an organisation identifier as a parameter — because there is nothing a caller could usefully supply.

Consider what the alternative costs. An interface accepting an organisation identifier must check on every route that the caller is entitled to the one they named, and a single route where that check is absent exposes everybody's data to anybody with a valid key. That is the most common serious defect in multi-organisation interfaces, and it is entirely avoided by not accepting the parameter.

A check you never have to write cannot be forgotten

The same reasoning appears elsewhere in this product — the supplier portal authorising by ownership rather than by permission, the file controller checking one thing and requiring the route to declare the rest. The pattern is to make the dangerous input unavailable rather than to validate it carefully everywhere, because "carefully everywhere" is a promise about every future route as well as every current one.

Writes by name, and visibly so

The interface began as reads only, and writes arrived as an explicit addition rather than a relaxation: create and update for items, customers and vendors, each under a write scope granted by name. A read scope — the umbrella included — never satisfies a write scope, so a key issued for reading still cannot alter anything.

That is worth stating plainly because "read only" is often a setting somebody can quietly widen, and here it is a property of the scope the key was issued with. The writes reach master data and stop there: stock moves only through adjustments in the product, a supplier's payout details are refused, a create honours an idempotency key so a retry returns the first result, and every write is recorded in the audit log against the key that made it.

Four read scopes, three of them narrow

Scope What it reaches
Inventory Items, categories and warehouses.
Sales Customers and invoices.
Procurement Suppliers and purchase orders.
Read everything An umbrella satisfying all three.

Each narrow area has a matching write scope, and there is a write umbrella beside them; none is implied by a read scope. The umbrella scope is described honestly in the documentation as convenient for a trusted internal integration and worth avoiding for a third party. That is the right advice to publish beside it, because the temptation with an umbrella scope is to use it for everything and the cost only appears when a key ends up somewhere it should not be.

A single route sits outside the resource scopes and requires only a valid key: the one that describes the key itself. It is what a client calls to confirm which organisation it is operating against and what it is entitled to, and it is the correct first call in any integration.

A narrow scope costs a decision once. An umbrella scope costs a decision every time the key moves.

The documentation and the routes come from one description

The published scope list is rendered from the same catalogue the interface is built around, rather than being maintained as a separate document. So the scopes described publicly and the scopes enforced on the routes cannot drift apart.

That matters more for an interface than almost anywhere else. Documentation is the contract, integrations are written against it by people you never speak to, and a documented scope that does not exist produces an integration that fails in production against a key its author configured exactly as instructed.

Public contract versus internal surface

There is a much larger interface behind this one, serving the product's own applications. It is explicitly not this: it is first-party, app-internal and undocumented, and it changes as the applications change.

Keeping the two separate is the discipline that makes a versioned public interface possible at all. A public surface is a promise that shapes stay stable; an internal one is a place where a screen and its data can evolve together. Merging them means either freezing internal development or breaking integrations, and both are worse than maintaining two.

For anybody building against this, the practical rule is short: if it is documented, it is a contract. If you found it by watching the product's own network traffic, it is not — and it will change without notice, because that is what the separation is for.

Scope, not a ceiling

Beyond master data

The surface is narrow, versioned and safe by construction, and it now writes master data. What integrators ask for next is more of it.

More read resources

Additional resources under the same scoping model — each one a scope, each one documented, each one carrying the organisation on the key.

Transaction writes

Invoices, orders and stock movements as explicit additions with their own scopes, under the same idempotency and audit contract the master-data writes already carry.

Events on every record change

Beyond the eight outbound webhook events, notification of any change rather than polling for one, which is what most integrations actually want from an interface.

We publish scope, not dates.

Scope an integration

Five questions to ask about a multi-organisation interface

How is the organisation determined?

A good answer sounds like

From the credential.

What ours actually is

From the key. No route accepts an organisation identifier from the caller, so there is nothing to validate and nothing to tamper with.

Can a key write anything?

A good answer sounds like

A definite answer.

What ours actually is

Only with a write scope granted by name, and only master data — items, customers and suppliers. A read key, the umbrella included, never writes.

What scopes exist?

A good answer sounds like

A published list.

What ours actually is

Inventory, sales and procurement, plus an umbrella that satisfies all three and is documented as being for trusted internal use.

Is the documentation generated from the implementation?

A good answer sounds like

Yes.

What ours actually is

The published scope list renders from the same catalogue the interface is built around, so the two cannot drift.

Is everything you call documented?

A good answer sounds like

No, and here is the line.

What ours actually is

No. A much larger first-party interface serves the product's own applications and is deliberately undocumented and unversioned.

Our take

The decision worth copying here is not a feature, it is an omission. By refusing to accept an organisation identifier from the caller, the interface makes the most consequential authorisation check in a multi-organisation system into something that cannot be forgotten, because there is no place to write it. Everything else follows comfortably from that: three narrow scopes and an honestly-labelled umbrella, and documentation rendered from the same description that enforces the routes. Writes came second, and that was the right order — they arrived with their own scopes, an idempotency contract and an audit entry per call, rather than as a relaxation of something built for reading.

The interface ledger, precisely

What AWRA OpsHub does today

  • A versioned, publicly documented interface for a workspace's own data, authenticated by a key minted inside that workspace.
  • The organisation carried by the key, with no route accepting an organisation identifier from the caller.
  • Create and update for items, customers and suppliers under write scopes granted by name, which no read scope satisfies — with an idempotency key on create and every write audited against the key.
  • Three narrow resource scopes covering stock, sales and purchasing, plus an umbrella scope documented as suited to trusted internal use.
  • A single route requiring only a valid key, describing the key's own organisation and entitlements, as the correct first call in any integration.
  • A rate limiter applied to the whole surface.
  • Outbound webhooks on eight events, signed, so an integration learns of the common changes without polling.
  • Cursor pagination stated as part of the documented contract, so a large collection can be walked with a stable guarantee.
  • Published documentation rendered from the same catalogue the interface is built around, so scopes cannot be documented without existing.
  • A clear separation from the much larger first-party interface serving the product's own applications, which is deliberately undocumented and unversioned.

More we can add to your workspace

  • Transaction writes — invoices, orders and stock movements — with their own scopes, under the idempotency and audit contract the master-data writes carry.
  • Additional read resources beyond stock, sales and purchasing — assets, people, projects and support each following the same scoping model.
  • Events on every record change, beyond the eight outbound webhook events, so an integration learns of any change rather than polling for one.
  • Field selection on a response, so a client can ask for what it needs rather than filtering a full record.
  • A per-key usage view, showing what a key has called and how often, inside the workspace that minted it.

Where we point you to a specialist

  • We will not accept an organisation identifier from a caller on this surface. The check that a caller is entitled to the organisation they named is the one most likely to be omitted from exactly one route, and the reliable way to guarantee it everywhere is to make the parameter unavailable.
  • We will not add writes by relaxing what exists. A write surface has different requirements — scopes, idempotency, limits, and a much more careful contract about partial success — which is why the master-data writes arrived under scopes of their own, and why a read key never satisfies one.
  • What is documented is a contract and what is not is not. The first-party interface serving our own applications changes as those applications change, and building against it is a decision to be broken; we would rather say so than let a version number imply a promise we are not making.

Events on every record change are the piece most integrations actually want, because the majority of polling against an interface exists only to discover that something changed.

Start with the narrow scope

The umbrella exists for convenience and it is the wrong default for anything leaving your organisation. Three narrow scopes cost one extra decision at setup and remove a whole category of regret.

Talk through the interface

Frequently asked questions

How does the interface know which organisation to serve?

From the key. It is minted inside a workspace and belongs to it, and every request authenticated by it is scoped accordingly. No route accepts an organisation identifier from the caller, which means the check that a caller is entitled to the organisation they named does not need to exist — and therefore cannot be missing from one route.

Can a leaked key be used to change our data?

A read key, no. Writing needs a write scope granted by name when the key is issued, and no read scope — the umbrella included — satisfies one. A key issued with a write scope can create and update items, customers and suppliers and nothing beyond that, and every write it makes is recorded in the audit log against the key, so issue write scopes only where an integration needs them.

Which scope should we grant?

The narrowest that covers what the integration needs — stock, sales or purchasing. The umbrella scope satisfies all three and is documented as suited to a trusted internal integration; for anything given to a third party, a narrow scope costs one extra decision at setup and bounds the consequences of the key ending up somewhere unexpected.

Where do I find the documentation?

It is published as part of the product, and it renders from the same catalogue the interface is built around rather than being maintained separately. That construction is deliberate: a documented scope that does not exist produces an integration that fails in production against a key its author configured exactly as instructed.

The product's own app calls endpoints I cannot find in the documentation. Can I use those?

You can, and they will break. Those belong to a first-party interface that serves the product's own applications and changes as they change — deliberately undocumented and unversioned. The line is simple: if it is documented, it is a contract; if you found it by watching network traffic, it is not.

Is there a write interface?

Yes, for master data: create and update for items, customers and suppliers, each under its own write scope. It arrived as its own thing rather than as a relaxation of the read surface — a create honours an idempotency key, every write is audited against the key, and stock moves only through adjustments in the product. Transaction writes are the next piece. Alongside it, the interface that already handles inbound integration calls is a different surface with a different arrangement.

Share this article

LinkedIn X WhatsApp

Help Center

Need a quick answer while you read?

Run inventory, procurement, assets, sales, and field work with approved AWRA guidance for setup, migration, integrations, security, pricing, and support.

Search all approved AWRA public help articles.

Open Help Center