> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getspine.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Install the SDK and run your first end-to-end request.

This walks through installing `spine-sdk`, creating a run, waiting for it
to finish, and downloading the generated artifacts. For a broader
conceptual tour of the API, see the [API quickstart](/api-reference/quickstart).

## 1. Install

```bash theme={"theme":{"light":"github-light","dark":"tokyo-night"}}
npm install spine-sdk
```

<Note>
  Requires Node.js 18 or newer. Also works in modern browsers, Deno, Bun,
  and Cloudflare Workers without any extra configuration.
</Note>

## 2. Get an API key

Create a key in the [developer portal](https://platform.getspine.ai/keys).
You get **\$5 of free credits** immediately — enough for several test
runs end-to-end. Keys look like `sk_spine_...` and are shown only once.

Export it into your environment so the SDK can pick it up:

```bash theme={"theme":{"light":"github-light","dark":"tokyo-night"}}
export SPINE_API_KEY=sk_spine_...
```

See [Authentication](/sdks/typescript/authentication) for key rotation,
staging overrides, and tracing hooks.

## 3. Run your first request

```ts theme={"theme":{"light":"github-light","dark":"tokyo-night"}}
import { writeFile } from 'node:fs/promises';
import { Spine, downloadArtifact } from 'spine-sdk';

const client = new Spine({ apiKey: process.env.SPINE_API_KEY! });

const run = await client.runs.create({
  prompt: 'Summarise the Q4 2025 AI chip market in three paragraphs.',
  template: 'memo',
});
console.log('Run started:', run.run_id);

const terminal = await client.runs.waitForCompletion(run.run_id);

if (terminal.status !== 'failed') {
  console.log(terminal.result.final_output);
  for (const artifact of terminal.result.artifacts) {
    const blob = await downloadArtifact(artifact);
    await writeFile(artifact.name, Buffer.from(await blob.arrayBuffer()));
  }
}
```

### What happens

1. `runs.create` submits the prompt and returns a `CreatedRun` handle
   immediately.
2. `waitForCompletion` polls `GET /v1/run/{run_id}` every 5 seconds until
   the run reaches a terminal state.
3. On success, `terminal.result.final_output` holds the synthesized
   markdown and `terminal.result.artifacts` lists downloadable files
   (docx, xlsx, pptx, html, png — depending on the template).

See [Runs and polling](/sdks/typescript/runs) for all the options.

## 4. Upload files with a run

```ts theme={"theme":{"light":"github-light","dark":"tokyo-night"}}
import { readFile } from 'node:fs/promises';

const data = await readFile('./market_data.pdf');
const run = await client.runs.create({
  prompt: 'Read the attached files and produce a 1-page summary.',
  template: 'report',
  files: [
    { data: new Uint8Array(data), filename: 'market_data.pdf', contentType: 'application/pdf' },
    { data: new TextEncoder().encode('# Supplementary context\n...'), filename: 'inline.md' },
  ],
});
```

Accepts `File`, `Blob`, `ArrayBuffer`, `Uint8Array`, or
`{ data, filename, contentType }` records. Supported types are documented
on [File uploads](/api-reference/concepts/file-uploads).

## 5. Handle errors

Every failure is a subclass of `SpineError`. Branch on the specific
types when you need to:

```ts theme={"theme":{"light":"github-light","dark":"tokyo-night"}}
import { Spine, SpineBadRequestError, SpineAuthError } from 'spine-sdk';

try {
  const client = new Spine({ apiKey: process.env.SPINE_API_KEY! });
  await client.runs.create({ prompt: '', template: 'bogus' as 'memo' });
} catch (err) {
  if (err instanceof SpineBadRequestError) {
    console.error('Rejected:', err.message);
  } else if (err instanceof SpineAuthError) {
    console.error('Check your SPINE_API_KEY');
  } else {
    throw err;
  }
}
```

See [Errors and retries](/sdks/typescript/errors) for the full hierarchy
and how transient failures are retried automatically.

## Next steps

<CardGroup cols={2}>
  <Card title="Runs and polling" icon="arrows-rotate" href="/sdks/typescript/runs">
    Stream progress, tune poll intervals, use the low-level `runs.retrieve`.
  </Card>

  <Card title="Canvas introspection" icon="diagram-project" href="/sdks/typescript/canvas">
    Inspect the block graph and task tree a run produced.
  </Card>
</CardGroup>
