API best practices
We recommend referring to our FAQ documentation. You will find answers to common queries and useful tips that can enhance your interaction with our API.
Keep API keys secret
Objective: Keep your account and data secure
Strategy:
- Never share API keys directly in email/chat/photo/text message. Instead, use a service such as https://onetimesecret.com to share a secret link.
- Only use API keys from server-side functions/backend scripts that use the Storeganise API. The keys should never be sent to the web browser/client/frontend.
- Do not use API keys in frontend websites (e.g. Javascript, React apps that are rendered in the browser). If you are building a customer booking flow, use the email/password combination with the User API endpoints (not Admin API endpoints).
- Do not expose API keys in your codebase. Use other approaches such as environment variables instead.
Restrict use of the include
query parameter
Context:
The include
query parameter in our API is designed to fetch related items in a single request. For example, GET /api/v1/user?include=units,items,billing,customFields
efficiently loads a comprehensive view of a user. It is made for loading a detail page for a single item, e.g. in a User Detail page.
We limit its use on list endpoints since it can be inefficient when many resources are being requested.
Implementation:
- Use
include
primarily for detailed single entity views where you can load what you need in one request rather than many. - Only request the related items you need; e.g. if loading a User Detail page where you want to show the user's units, just ask for the units:
GET /api/v1/user?include=units
- Avoid using
include
on list endpoints; if you do, restrict it to small lists (e.g. <50 items). - Do not use
include
when exporting data; instead, load data from the relevant endpoints, e.g.GET /api/v1/admin/units
and thenGET /api/v1/admin/users
, etc. Each item has parameters like `ownerId`, etc. which can be used for knowing which items are related.
Cache common, static API calls
Objective: Improve performance and reduce unnecessary API traffic.
Strategy: Cache the results of these calls, as they typically return static or rarely changed data.
Example use cases:
GET /settings
GET /admin/settings
Use ?updatedAfter=YYYY-MM-DDTHH:MM:SS.000Z
for efficient data synchronization
Objective: Improve performance by fetching only recently changed items.
Use Case: Syncing invoices, users, etc., to external systems.
Implementation:
- Append the
updatedAfter
query parameter with a timestamp to only fetch items that have been updated since that date. - This date would often be the date of the last sync.
- Use the UTC timezone (see examples below)
Examples:
GET /admin/users?updatedAfter=2024-01-01T00:00:00.000Z
GET /admin/invoices?updatedAfter=2023-12-31T14:00:00.000Z
Make requests in series
Objective: Avoid overloading the server with simultaneous requests.
Context: Useful when loading extensive lists (invoices, users, units, etc.).
Approach: Wait for a request to complete before initiating the next one, rather than sending all requests simultaneously.
Use ?ids=id1,id2,id3
for fetching in batches
Objective: Efficiently retrieve multiple specific items in a single request.
Alternative to: Making individual requests like GET /admin/users/userId1
, GET /admin/users/userId2
Recommended Method: Fetch multiple items (up to 50) simultaneously.
Examples:
GET /admin/users?ids=userId1,userId2
GET /admin/invoices?ids=invoiceId1,invoiceId2
Fetch specific items by id
or code
Objective: Optimize data retrieval by using direct identifiers.
Avoid: Generic searches like GET /admin/sites?search=customField:foo
.
Prefer: Direct access using unique identifiers.
Examples:
GET /admin/sites/siteIdOrCode
GET /admin/users/userIdOrEmail