Skip to main content

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:
Set 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

You don’t need a GraphQL-specific client. httpx handles the transport. tenacity gives you declarative retry. If you prefer the gql library, these patterns translate directly.

Build the client

You only call 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:
If this fails, see the 401 table in Error codes. The error message names the fix.

List parts

Create a run

Replace procedureId and partInventoryId with real IDs from your org. To find candidate procedures, see Example requests.

Submit a run step result

The 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:
You must capture the S3 ETag. You must fetch entity.id, not the parent’s id. Both are documented in File upload.

Error handling pattern

The IonClient 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:
For the full HTTP status reference and the GraphQL 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:
This keeps field selection consistent across calls. A forgotten field, such as _etag, becomes a one-line fix instead of a multi-file refactor.