Overview
Each function in this guide maps to one ION operation that you can lift into your own codebase. The script needs two environment variables:ION_BASE_URL to your region’s API endpoint, without /graphql. For the endpoint that matches your app URL, see Getting started.
If you don’t have a token yet, see Getting a token.
Set up the environment
httpx handles the transport. tenacity gives you declarative retry. If you prefer the gql library, these patterns translate directly.
Build the client
IonClient.query and IonClient.mutate. _post_graphql handles transport-level retries for 5xx and network errors. It surfaces GraphQL-level errors as IonError.
Confirm the token works
Check who you are authenticated as before you do anything else:List parts
Create a run
procedureId and partInventoryId with real IDs from your org. To find candidate procedures, see Example requests.
Submit a run step result
etag field is required on update. For details, see Etag-based concurrency. If you get a 409, re-fetch the run step, take its new etag, and retry.
Upload a file attachment
This is the full three-step pattern from File upload:entity.id, not the parent’s id. Both are documented in File upload.
Error handling pattern
TheIonClient raises IonError on GraphQL-level errors and uses tenacity for transport retries. Wrap your business logic in a try and except block that handles each error type:
errors[] payload shape, see Error codes.
Reuse fragments
When several queries return the same entity, such as parts, runs, or purchase orders, define one fragment per entity and inline it everywhere:_etag, becomes a one-line fix instead of a multi-file refactor.