# How to Use the Astryx JSON API Programmatically for AI Agent Integration

> Integrate AI agents with the Astryx JSON API. Learn to parse responses, handle errors, and discover capabilities programmatically for seamless AI agent integration. Explore the Astryx API now.

- Repository: [Meta/astryx](https://github.com/facebook/astryx)
- Tags: how-to-guide
- Published: 2026-07-02

---

**The Astryx JSON API provides a typed, machine-readable interface for every CLI command, enabling AI agents to parse responses, handle errors deterministically, and discover capabilities through a self-describing manifest.**

The facebook/astryx repository ships a sophisticated JSON API that transforms the Astryx CLI into a programmable interface for automation tools and AI agents. By appending the `--json` flag to any command, the CLI emits structured envelopes instead of human-readable text, complete with TypeScript definitions that ensure type safety across the boundary between shell execution and application logic.

## Understanding the JSON API Architecture

The Astryx JSON API is implemented as a thin serialization layer over the existing CLI infrastructure. Every command checks for the `--json` flag and, when present, outputs responses using typed helper functions rather than console formatting.

### The Envelope Structure

Every JSON response follows a strict envelope pattern defined in [`packages/cli/src/types/base.d.ts`](https://github.com/facebook/astryx/blob/main/packages/cli/src/types/base.d.ts). Successful responses return:

```json
{ "type": "<discriminator>", "data": { … } }

```

Error responses use a complementary shape:

```json
{ "error": "...", "code": "<ERR_…>", "suggestions": […] }

```

The **type discriminators** (such as `component.detail`, `search`, or `manifest`) function as tagged unions that allow TypeScript to narrow response types automatically.

### Core Type Definitions

The type system lives in `packages/cli/src/types/` and provides compile-time guarantees for AI agent integrations:

- **[`base.d.ts`](https://github.com/facebook/astryx/blob/main/base.d.ts)** – Defines the generic `CLIResult<T>`, `CLIError`, and the union `CLIAnyResponse`. It also exports helper functions including `jsonOut`, `jsonError`, `parseResponse`, `isError`, and `assertResponse`.
- **[`component.d.ts`](https://github.com/facebook/astryx/blob/main/component.d.ts)** – Describes component-related responses such as `ComponentDetailResponse`, specifying fields like `name`, `props`, and `source`.
- **[`manifest.d.ts`](https://github.com/facebook/astryx/blob/main/manifest.d.ts)** – Exposes the self-describing capability manifest via `ManifestResponse`, which agents use to discover commands and their JSON support.

## Consuming the API at Three Levels

Because the API is **pure data**, you can integrate it at three distinct abstraction levels depending on your runtime constraints.

### Shell-Level Integration

Spawn a child process with the `--json` flag and parse the stdout stream. This approach works across any language or runtime that can execute shell commands, making it ideal for polyglot AI agent systems.

### Node-Level Integration

Import the helper functions directly from `@astryxdesign/cli/json` to reuse the CLI's internal serialization logic in custom scripts or libraries. This eliminates string parsing and provides immediate access to the type definitions.

### Agent-Level Discovery

Execute `astryx manifest --json` to retrieve a "mini-OpenAPI" description of every command, its arguments, flags, and JSON support status. AI agents can fetch this manifest once at startup and generate calling code dynamically without hard-coding response shapes.

## Implementation Examples

### Calling Astryx via Child Process

For generic AI agents running in isolated environments, spawn the CLI and parse the response using the built-in helpers:

```typescript
import { execFile } from 'node:child_process';
import { parseResponse, isError } from '@astryxdesign/cli/json';

async function runAstryx(command: string[], cwd = process.cwd()) {
  return new Promise<{ stdout: string; stderr: string }>((resolve, reject) => {
    execFile('npx', ['astryx', ...command, '--json'], { cwd }, (err, stdout, stderr) => {
      if (err) reject(err);
      else resolve({ stdout, stderr });
    });
  });
}

// Example: fetch details for the Button component
const { stdout } = await runAstryx(['component', 'Button']);
const result = parseResponse(JSON.parse(stdout));

if (isError(result)) {
  console.error('Astryx error:', result.code, result.error);
} else {
  // `result` is now narrowed to ComponentDetailResponse
  console.log('Component docs URL:', result.data.docUrl);
}

```

This pattern uses the `parseResponse` and `isError` helpers defined in [`packages/cli/src/types/base.d.ts`](https://github.com/facebook/astryx/blob/main/packages/cli/src/types/base.d.ts) to handle both success and error envelopes safely.

### Direct Programmatic Usage

When running within a Node.js context where you can import the CLI library, emit responses using the same primitives the CLI uses internally:

```typescript
import { jsonOut, jsonError } from '@astryxdesign/cli/json';
import type { ComponentDetailResponse } from '@astryxdesign/cli/json';

// Simulate a command implementation inside a custom script
function getButtonInfo(): ComponentDetailResponse {
  return {
    type: 'component.detail',
    data: {
      name: 'Button',
      props: [],
      source: 'packages/core/src/Button/Button.tsx',
    },
  };
}

// Emit a proper JSON envelope
jsonOut('component.detail', getButtonInfo().data);

```

The `jsonOut` function guarantees that the payload matches the declared shape according to the contracts in [`base.d.ts`](https://github.com/facebook/astryx/blob/main/base.d.ts).

### Discovering Capabilities via Manifest

AI agents can introspect the CLI's capabilities before executing commands:

```typescript
import { execFileSync } from 'node:child_process';
import { parseResponse } from '@astryxdesign/cli/json';

const raw = execFileSync('npx', ['astryx', 'manifest', '--json'], { encoding: 'utf8' });
const manifest = parseResponse(JSON.parse(raw)); // type = ManifestResponse

if (!('commands' in manifest.data)) {
  throw new Error('Unexpected manifest shape');
}

// Find all commands that support JSON output
const jsonCommands = manifest.data.commands.filter(c => 
  c.flags.some(f => f.flag === '--json')
);
console.log('Commands with JSON support:', jsonCommands.map(c => c.name));

```

The manifest schema resides in [`packages/cli/src/types/manifest.d.ts`](https://github.com/facebook/astryx/blob/main/packages/cli/src/types/manifest.d.ts) and is exposed via the `ManifestResponse` type.

### Asserting Specific Response Types

For type-safe narrowing when you expect a specific discriminator, use the assertion helper:

```typescript
import { assertResponse } from '@astryxdesign/cli/json';
import type { SearchResponse } from '@astryxdesign/cli/json';

const raw = execFileSync('npx', ['astryx', 'search', 'button', '--json'], { encoding: 'utf8' });
const response = assertResponse(JSON.parse(raw), 'search'); // narrows to SearchResponse

console.log('Top result:', response.data.results[0].name);

```

The `assertResponse` function throws if the envelope does not match the expected discriminator, providing runtime validation that complements the static types in [`component.d.ts`](https://github.com/facebook/astryx/blob/main/component.d.ts) and related files.

## Error Handling and Type Safety

Always use the **type guard** `isError(result)` to differentiate success from failure before accessing response data. This function checks for the presence of the `error` field and narrows the union type to `CLIError`, exposing the stable `code` field for programmatic error handling.

For stricter validation, the `assertResponse` helper validates that the `type` discriminator matches your expected string, throwing immediately if an unexpected response shape arrives. This prevents type confusion when integrating with third-party AI agents that may misparse outputs.

## Summary

- **Astryx JSON API** responses follow a strict envelope pattern with `type` discriminators and `data` payloads, or error objects with stable codes.
- **Type definitions** in [`packages/cli/src/types/base.d.ts`](https://github.com/facebook/astryx/blob/main/packages/cli/src/types/base.d.ts) provide `CLIResult<T>`, `CLIError`, and helper functions like `isError` and `assertResponse`.
- **Three integration levels** support shell-level parsing, direct Node.js imports from `@astryxdesign/cli/json`, and agent-level discovery via `astryx manifest --json`.
- **Error handling** relies on the `isError` type guard to safely narrow response unions before accessing data properties.

## Frequently Asked Questions

### What is the envelope format for Astryx JSON API responses?

Successful responses return a JSON object with `type` and `data` fields, where `type` acts as a discriminator (e.g., `component.detail`, `search`). Error responses return an object with `error`, `code`, and optional `suggestions` fields. This format is defined in [`packages/cli/src/types/base.d.ts`](https://github.com/facebook/astryx/blob/main/packages/cli/src/types/base.d.ts) as `CLIResult<T>` and `CLIError`.

### How do I handle errors when calling Astryx commands programmatically?

Import the `isError` type guard from `@astryxdesign/cli/json` to narrow the response type. If `isError(result)` returns true, the response contains `error` and `code` fields that provide stable identifiers for programmatic error handling. Alternatively, use `assertResponse` to throw immediately if the response type does not match expectations.

### Can AI agents discover available Astryx commands automatically?

Yes. By running `astryx manifest --json`, agents retrieve a `ManifestResponse` containing descriptions of every command, including available flags and JSON support status. Agents can parse this manifest to determine which commands support JSON output and what arguments they require, eliminating the need for hard-coded command lists.

### What package should I import for TypeScript type definitions?

Install and import from `@astryxdesign/cli/json` to access helper functions (`parseResponse`, `jsonOut`, `isError`, `assertResponse`) and response types (`ComponentDetailResponse`, `SearchResponse`, `ManifestResponse`). These definitions mirror the source files in `packages/cli/src/types/` and ensure your AI agent code remains synchronized with the CLI implementation.