@antigenco/sdk is the typed client for Antigen Runs. It offers two entry points into the same
API. Use antigen.agent(config).run(targets) when the model and Guardrails belong together as one
assessment configuration. Use antigen.runs when your application owns the request fields, or when
it is reconnecting to a Run it created earlier.
An integration owns three things: an organization API key, an approved target, and durable storage
for the Run ID. Antigen supplies the approved target list; you choose from it and record why the
target is in scope. A Run ID is a locator rather than a credential, so store it alongside the
assessment record and rely on organization permissions for every later read or operation.
Install
Authenticate
Pass an organization API key as the first argument. Keys begin withatg_sk_; read them from your
secret source at startup and never commit or log them.
atg_sk_ prefix identifies the credential kind, not its validity, expiry, or scope, so a shape
check cannot tell you whether a key still works. The service answers that with a structured error
carrying a requestId.
Later examples on this page assume this antigen client and an approved target string already
exist, so that each one shows only the call being described.
Quick start
This complete program picks an approved target, creates a Run, follows its events, and prints the first finding’s remediation. Save it asassess.ts and run it with npx tsx assess.ts.
Client
new Antigen
Constructs a client. The common form takes an API key; the object form is for callers that hold a user access token or need to reach a non-hosted environment.
The object form is the one to reach for when a value other than an API key varies:
apiKey and accessToken. Supplying both, neither, a blank credential, or an
apiKey without the atg_sk_ prefix throws AntigenProtocolError from the constructor. baseUrl
is validated the same way: it must be an http or https URL carrying no query, fragment, or
embedded credentials.
The client exposes antigen.runs for the Run collection and antigen.agent(config) for the
assessment facade. Constructing a client performs no network request, so a well-formed but invalid
credential is reported by the service on the first call, not here.
antigen.getApprovedTargets
Lists the targets approved for the caller’s organization. Call it before creating a Run.TARGET_NOT_APPROVED, read this list
again rather than editing the rejected target. An empty list is an authorization question for your
organization administrator, not an integration bug.
Create a Run
antigen.agent
Creates an assessment facade that keeps model configuration and Guardrails next to Run creation.
Each
skills entry may be a .md file or a directory, which is walked in deterministic order.
Symbolic links are rejected, empty files are rejected, and each Skill’s name is its filename without
the extension, so names must be unique across the whole set. Treat these files as reviewed
application input and keep credentials out of them.
agent.run
Creates a Run from the Agent’s configuration for one or more approved targets.targets must be non-empty and every entry must come from getApprovedTargets. Invalid input,
transport failures, and service rejections reject rather than returning a partial Run, so a
resolved promise always carries a real run.id.
Persist run.id immediately. If the create response is ambiguous, read that saved ID with
runs.get before deciding whether another assessment is necessary. A second create is a
new assessment record, never a retry.
runs.create
Creates a Run from request fields your application supplies directly. Use this form when the application, rather than an Agent configuration, owns the request.agent.run, this form takes Skill content inline rather than reading local paths, so it
works in runtimes without filesystem access. Pick one creation form per integration boundary.
Find a Run
runs.list
Reads a page of Runs visible to the caller’s organization.runs are full Run objects, so you can act on one without a second read. Preserve nextCursor
unchanged and pass it back only for the next page. Do not derive authorization, identity, or
ordering from a cursor or a Run ID.
runs.get
Reads a known Run by its saved opaque ID. This is the entry point for every recovery path.RUN_NOT_FOUND and authorization failures reject: the ID alone does not grant access. Read a saved
Run before retrying any ambiguous create or lifecycle request.
Observe a Run
ARun separates the durable assessment record from what your caller has observed. run.current
holds the last representation the client saw, without making a request. The methods below refresh
it. Process evidence before advancing its saved checkpoint.
run.status
Reads and refreshes the latest durable representation of the Run.RunState is a discriminated union on status, so the timestamps it carries depend on how far the
Run has progressed: startedAt once running, stoppedAt when stopped, completedAt on a terminal
state, and a failure object of { code, message } when status is failed.
Read status after an ambiguous create, a lifecycle action, a local wait, or an event interruption,
before deciding on the next operation.
run.events
Streams ordered events and resumes cleanly after a handled checkpoint.
A
Run is itself async-iterable, so for await (const event of run) is shorthand for
run.events() with no options.
sequence, summary, timestamp, and an optional originating agent of
planner, recon, executor, or system. Switch on type for the rest:
The SDK reconnects a dropped stream on your behalf and recognizes exact duplicate replay within the
most recent 256 events. Out-of-order or unknown older events are protocol errors rather than silent
gaps. Persist
event.sequence only after handling the event; saving first can skip unprocessed
work, and never saving makes the same evidence look new after every interruption.
run.findings
Reads durable findings for the Run.
A completed Run can have no findings; that is a valid assessment result, not an integration
failure. Treat findings as evidence for a human risk decision, and preserve
proof and
remediation with the assessment record. A local failure does not mean a finding was removed.
run.wait
Waits locally until the Run reachescompleted, failed, or cancelled.
stopped is not wait-terminal, so a stopped Run keeps the wait running until the deadline. The
deadline is local: on AntigenWaitTimeoutError, reconnect with runs.get and
run.events rather than assuming the Run ended or calling run.cancel.
Guide a Run
run.send
Delivers scoped guidance to an assessment already under way, without changing its approved purpose.content must be non-empty and stay inside the approved target and Guardrails. Prefer a specific,
reviewable request over a broad change of purpose. If necessary work falls outside the approved
scope, obtain authorization and create a separate assessment instead.
Control a Run
completed, failed, and cancelled are terminal. Use a lifecycle operation to express a
decision, not to repair a local timeout. If one is rejected with INVALID_RUN_STATE, another
transition already occurred: read the Run and choose an action valid for the observed state.
run.stop
Requests a reviewable pause, leaving the Run resumable.run.resume
Requests continuation of a stopped Run you already hold.runs.resume
Resumes a stopped Run by ID and returns aRun object for it. Use this when the application has a
saved ID but not a live Run, which is the usual case after a restart.
agent.resume(runId, options) is an equivalent alias on the Agent facade, for code that is already
working through an Agent. It ignores the Agent’s model and Guardrails, because a resumed Run keeps
the configuration it was created with.
run.cancel
Ends the assessment.cancelled is terminal.
Request options
Every method acceptsRequestOptions as its last argument. Both fields bound the caller’s own work
and neither changes a Run that Antigen has already accepted.
run.wait extends these with waitTimeoutMs and pollIntervalMs, and
run.events extends them with after.
Errors
The SDK distinguishes local wait timeouts, protocol failures, and HTTP failures. Transport failures surface as the underlyingfetch error.
code in its body. Retain the requestId with the
saved Run ID: it lets support identify the failing request without exposing credentials.
Recover from an ambiguous result
When a create, lifecycle, or observation call fails, the local failure tells you what your caller knows. It does not establish what the Run did. Recovery is always the same shape:- Read the saved Run ID from your durable store.
- Call
runs.get, thenrun.statusfor its current state. - Continue
run.eventsstrictly after the last sequence you finished handling. - Read
run.findingsfor durable remediation work.
run.cancel because a wait expired. Both turn an unknown local state into a real change to
the assessment record.
Related concepts: Guides, Examples, HTTP API reference, and
Reliability and security.