Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 97 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@

[![NPM version](<https://img.shields.io/npm/v/landingai-ade.svg?label=npm%20(stable)>)](https://npmjs.org/package/landingai-ade) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/landingai-ade)


**[Playground](https://va.landing.ai) · [Discord](https://discord.com/invite/RVcW3j9RgR) · [Blog](https://landing.ai/blog) · [Docs](https://docs.landing.ai)**

</div>


This library provides convenient access to the LandingAI ADE REST API from server-side TypeScript or JavaScript.

The REST API documentation can be found on [docs.landing.ai](https://docs.landing.ai/). The full API of this library can be found in [api.md](api.md).
Expand Down Expand Up @@ -49,7 +47,11 @@ const client = new LandingAIADE({
environment: 'eu', // defaults to 'production'
});

const response = await client.parse({ document: fs.createReadStream('path/to/file'), model: 'dpt-2-latest', saveTo: './output_folder' });
const response = await client.parse({
document: fs.createReadStream('path/to/file'),
model: 'dpt-2-latest',
saveTo: './output_folder',
});
// optional: saves as {input_file}_parse_output.json in the specified folder

console.log(response.chunks);
Expand Down Expand Up @@ -102,14 +104,14 @@ const schema = {
properties: {
name: {
type: 'string',
description: "Person's name"
description: "Person's name",
},
age: {
type: 'number',
description: "Person's age"
}
description: "Person's age",
},
},
required: ['name', 'age']
required: ['name', 'age'],
};

const client = new LandingAIADE({
Expand All @@ -118,14 +120,14 @@ const client = new LandingAIADE({

const response = await client.extract({
schema: JSON.stringify(schema),
markdown: fs.createReadStream('path/to/file.md')
markdown: fs.createReadStream('path/to/file.md'),
});
```

For advanced type-safe schemas with full TypeScript inference, see [Using Zod for Type-Safe Schemas](#using-zod-for-type-safe-schemas).


### Split

Split parsed documents into separate sections based on classification rules and identifiers.

```js
Expand Down Expand Up @@ -170,6 +172,83 @@ for (const split of splitResponse.splits) {
}
```

### V2 API (`client.v2`)

`client.v2` is a new, **additive** sub-client for LandingAI's next-generation ADE gateway. It does not change anything about the V1 usage above — `client.parse`, `client.extract`, `client.parseJobs`, etc. keep working exactly as documented. Use `client.v2.*` for the newer parse/extract surface.

The V2 gateway lives on its own host (`aide.[env].landing.ai`), separate from the V1 host (`api.va.[env].landing.ai`). Select the environment the same way as V1 — via the `environment` option or the `LANDINGAI_ADE_ENVIRONMENT` env var:
Comment thread
tian-lan-landing marked this conversation as resolved.
Outdated

<!-- prettier-ignore -->
```ts
import fs from 'fs';
import LandingAIADE from 'landingai-ade';

const client = new LandingAIADE({
apikey: process.env['VISION_AGENT_API_KEY'],
environment: 'staging', // 'production' | 'eu' | 'staging' | 'dev'
Comment thread
tian-lan-landing marked this conversation as resolved.
Outdated
});

// Synchronous parse / extract
const parsed = await client.v2.parse({ document: fs.createReadStream('doc.pdf') });
const extracted = await client.v2.extract({
schema: { type: 'object', properties: { title: { type: 'string' } } },
markdown: parsed.markdown ?? '',
});
```
Comment thread
tian-lan-landing marked this conversation as resolved.
Outdated

`schema` accepts a JSON-Schema object or a JSON-encoded string. For type-safe schemas, define them with Zod and pass `z.toJSONSchema(MySchema)` (see [Using Zod for Type-Safe Schemas](#using-zod-for-type-safe-schemas)). A synchronous 504 surfaces as `V2SyncTimeoutError` — use the async jobs route below for long-running documents.

#### Async jobs

`parseJobs` / `extractJobs` create jobs and return one unified `Job` shape regardless of the divergent upstream envelopes (the full envelope stays on `Job.raw`). `wait()` polls with backoff until the job is terminal:

<!-- prettier-ignore -->
```ts
const job = await client.v2.parseJobs.create({
document: fs.createReadStream('large.pdf'),
service_tier: 'priority',
});
const done = await client.v2.parseJobs.wait(job.job_id, { timeout: 600000, raiseOnFailure: true });
console.log(done.status, done.result);

// client.v2.extractJobs.{create,get,list,wait} mirror the same shape for extract jobs.
```

#### File staging

`client.v2.files.upload` stages bytes on the ADE data plane and returns a `file_ref` you can pass as `markdown_ref` to extract:

<!-- prettier-ignore -->
```ts
const fileRef = await client.v2.files.upload({ file: fs.createReadStream('doc.md') });
const result = await client.v2.extract({ schema: { type: 'object' }, markdown_ref: fileRef });
```

`client.v2.parse` and `client.v2.extract` also accept `saveTo`, with the same auto-naming behavior as the V1 methods above.

#### Workflows (`parse-extract`)

`client.v2.workflow` runs a prebuilt pipeline (Phase 1: `parse-extract`) in one call — parse a document, then extract against a schema. Reference documents by `document_url`, or upload with `files.upload` and pass the returned ref as `document_ref`:

<!-- prettier-ignore -->
```ts
const result = await client.v2.workflow({
inputs: { report: { document_url: 'https://example.com/report.pdf' } },
steps: [
{
name: 'parse-extract',
document: '$inputs.report',
schema: { type: 'object', properties: { revenue: { type: 'string' } } },
},
],
});
console.log(result.output['parse-extract']);

// Async: client.v2.workflowJobs.{create,get,list,wait} mirror the jobs shape above.
```

To send a local file instead of a URL, pass it as `inputs.<name>.document` (the SDK stages it as a multipart part), or upload it first with `files.upload` and pass the returned ref as `document_ref`.

### Request & Response types

This library includes TypeScript definitions for all request params and response fields. You may import and use them like so:
Expand Down Expand Up @@ -237,12 +316,14 @@ const InvoiceSchema = z.object({
name: z.string(),
address: z.string().optional(),
}),
items: z.array(z.object({
description: z.string(),
quantity: z.number().int().positive(),
unitPrice: z.number().positive(),
total: z.number().positive(),
})),
items: z.array(
z.object({
description: z.string(),
quantity: z.number().int().positive(),
unitPrice: z.number().positive(),
total: z.number().positive(),
}),
),
totalAmount: z.number().describe('Total amount due'),
});

Expand All @@ -265,7 +346,7 @@ const result = await client.extract({
// 5. The extraction is now typed as Invoice
const invoice: Invoice = result.extraction as Invoice;
console.log(invoice.invoiceNumber); // TypeScript knows this is a string
console.log(invoice.totalAmount); // TypeScript knows this is a number
console.log(invoice.totalAmount); // TypeScript knows this is a number
```

Note: Zod is optional. You can also pass JSON Schema strings directly to the `extract` endpoint if you prefer.
Expand Down
36 changes: 36 additions & 0 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,39 @@ Methods:
- <code title="post /v1/ade/parse/jobs">client.parseJobs.<a href="./src/resources/parse-jobs.ts">create</a>({ ...params }) -> ParseJobCreateResponse</code>
- <code title="get /v1/ade/parse/jobs">client.parseJobs.<a href="./src/resources/parse-jobs.ts">list</a>({ ...params }) -> ParseJobListResponse</code>
- <code title="get /v1/ade/parse/jobs/{job_id}">client.parseJobs.<a href="./src/resources/parse-jobs.ts">get</a>(jobID) -> ParseJobGetResponse</code>

# V2

The `client.v2` sub-client targets LandingAI's next-generation ADE gateway on its own host (`aide.[env].landing.ai`), separate from the V1 host (`api.va.[env].landing.ai`). It is **additive** — `client.v2.*` is a separate surface from the top-level `client.*` (V1) methods above, and using it does not change any V1 behavior.

`client.v2.parseJobs` and `client.v2.extractJobs` both return a single, unified <a href="./src/resources/v2/types.ts">`Job`</a> shape even though the underlying parse/extract job envelopes differ upstream — `Job.raw` retains the full original envelope as an escape hatch.

Types:

- <code><a href="./src/resources/v2/types.ts">Job</a></code>
- <code><a href="./src/resources/v2/types.ts">JobError</a></code>
- <code><a href="./src/resources/v2/types.ts">JobList</a></code>
- <code><a href="./src/resources/v2/types.ts">JobStatus</a></code>
- <code><a href="./src/resources/v2/types.ts">V2ParseResponse</a></code>
- <code><a href="./src/resources/v2/types.ts">V2ExtractResult</a></code>
- <code><a href="./src/resources/v2/types.ts">V2WorkflowResult</a></code>
- <code><a href="./src/resources/v2/types.ts">V2FileUploadResponse</a></code>

Methods:

- <code title="post /v2/parse">client.v2.<a href="./src/resources/v2/v2.ts">parse</a>({ ...params }) -> V2ParseResponse</code>
- <code title="post /v2/extract">client.v2.<a href="./src/resources/v2/v2.ts">extract</a>({ ...params }) -> V2ExtractResult</code>
- <code title="post /v2/parse/jobs">client.v2.parseJobs.<a href="./src/resources/v2/parse.ts">create</a>({ ...params }) -> Job</code>
- <code title="get /v2/parse/jobs/{job_id}">client.v2.parseJobs.<a href="./src/resources/v2/parse.ts">get</a>(jobID) -> Job</code>
- <code title="get /v2/parse/jobs">client.v2.parseJobs.<a href="./src/resources/v2/parse.ts">list</a>({ ...params }) -> JobList</code>
- <code>client.v2.parseJobs.<a href="./src/resources/v2/parse.ts">wait</a>(jobID, { ...options }) -> Job</code>
- <code title="post /v2/extract/jobs">client.v2.extractJobs.<a href="./src/resources/v2/extract.ts">create</a>({ ...params }) -> Job</code>
- <code title="get /v2/extract/jobs/{job_id}">client.v2.extractJobs.<a href="./src/resources/v2/extract.ts">get</a>(jobID) -> Job</code>
- <code title="get /v2/extract/jobs">client.v2.extractJobs.<a href="./src/resources/v2/extract.ts">list</a>({ ...params }) -> JobList</code>
- <code>client.v2.extractJobs.<a href="./src/resources/v2/extract.ts">wait</a>(jobID, { ...options }) -> Job</code>
- <code title="post /v1/files">client.v2.files.<a href="./src/resources/v2/files.ts">upload</a>({ file }) -> string</code>
- <code title="post /v2/workflow">client.v2.<a href="./src/resources/v2/v2.ts">workflow</a>({ ...params }) -> V2WorkflowResult</code>
- <code title="post /v2/workflow/jobs">client.v2.workflowJobs.<a href="./src/resources/v2/workflow.ts">create</a>({ ...params }) -> Job</code>
- <code title="get /v2/workflow/jobs/{job_id}">client.v2.workflowJobs.<a href="./src/resources/v2/workflow.ts">get</a>(jobID) -> Job</code>
- <code title="get /v2/workflow/jobs">client.v2.workflowJobs.<a href="./src/resources/v2/workflow.ts">list</a>({ ...params }) -> JobList</code>
- <code>client.v2.workflowJobs.<a href="./src/resources/v2/workflow.ts">wait</a>(jobID, { ...options }) -> Job</code>
Loading
Loading