---
title: Continue in Basalt — Handoff API
description: Send a bounded external artifact into Basalt through an explicit preview-and-accept continuation flow.
slug: handoff
path: /handoff
section: Integrations
availability: supported
nav_order: 4
canonical_url: https://developers.basaltnotes.com/handoff
markdown_url: https://developers.basaltnotes.com/handoff.md
mirror_url: https://basaltnotes.com/developers/handoff
---
# Continue in Basalt — Handoff API

Basalt Handoff v1 lets an authorized external server offer **Continue in Basalt**, **Save to Basalt**, or **Open in Basalt** for one bounded work product.

A Handoff is a one-time ingress event. It is not ongoing synchronization, a Connection, trusted-memory promotion, a domain entitlement, or an instruction channel to an agent.

## Flow

```text
External product
    ↓ POST /api/handoffs
bounded temporary envelope
    ↓ opaque continueUrl
user signs in / creates Free account
    ↓
preview
    ↓ explicit accept
normal Basalt capture/import path
    ↓
user-owned knowledge + provenance
```

Opening a Handoff URL never imports content by itself.

[Machine-readable Handoff reference](/api/content/developers/references/handoff.json)

## Create a Handoff

```http
POST /api/handoffs
Authorization: Bearer bhc_your_server_credential
Content-Type: application/json
```

```json
{
  "schema": "basalt.handoff",
  "version": 1,
  "intent": "knowledge.capture",
  "provider": "your-product",
  "externalId": "artifact-42",
  "idempotencyKey": "your-product:artifact-42:v1",
  "artifact": {
    "type": "markdown",
    "title": "Example artifact",
    "contentType": "text/markdown",
    "content": "# Useful work\n\nSource-backed content."
  },
  "sources": [],
  "attachments": [],
  "relationships": [],
  "provenance": {
    "createdAt": "2026-08-15T00:00:00.000Z",
    "sourceUrl": "https://your-product.example/work/42",
    "generator": "your-product-v1"
  },
  "returnUrl": "https://your-product.example/work/42",
  "attribution": {
    "source": "your-product",
    "campaign": "continue-in-basalt",
    "medium": "handoff"
  }
}
```

The response includes an opaque continuation URL. Redirect the user to that URL. Never put the payload, external title, client credential, source URL, or marketing attribution into the continuation URL.

## Supported V1 vocabulary

Intents:

- `knowledge.capture`
- `artifact.continue`
- `research.continue`

Artifact types:

- `note`
- `markdown`
- `structured`
- `research`
- `source-set`
- `document`
- `pdf`

Routing hints such as a vertical/product continuation target do not activate commercial entitlements.

## Current limits

The V1 contract currently bounds:

- inline content to 64 KiB;
- normalized envelope to 96 KiB;
- structured data to 32 KiB;
- sources to 50;
- relationships to 50;
- attachment references to 10.

Attachment URLs are references only. Handoff does not automatically fetch arbitrary remote attachment URLs.

## Idempotency

Use a stable idempotency key for one external artifact version. Identical pending retries should resolve to the same continuation intent rather than creating duplicate staged knowledge.

Basalt also derives a knowledge fingerprint from normalized content. A materially changed external artifact may intentionally create a new version/handoff.

Acceptance is duplicate-safe: refresh, back navigation, and authentication redirects must not cause multiple imports.

## Retention

Staged Handoff payloads expire after the bounded V1 retention period (currently 48 hours). Payload data is removed after acceptance, cancellation, or expiry according to the Handoff contract.

Unauthenticated visitors should receive only safe provider/type/count metadata, not staged user-generated content.

## Trust and provenance

External content remains inert Draft data until the user accepts it. It cannot:

- override Basalt system/tool policy;
- confirm a Strata decision;
- execute Forge;
- promote trusted memory;
- trigger arbitrary URL fetching;
- grant a vertical/product entitlement.

Basalt preserves knowledge provenance separately from acquisition attribution. Marketing attribution must never become evidence.

## Free account behavior

A user arriving from a Handoff can create a Free Basalt account, preview the staged artifact, choose a destination, and accept it without being forced through a paid upgrade first.

## Server-side example

```js
const response = await fetch(`${BASALT_ORIGIN}/api/handoffs`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.BASALT_HANDOFF_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(envelope)
});

if (!response.ok) throw new Error(`Basalt Handoff failed: ${response.status}`);
const handoff = await response.json();
// Redirect the user's browser to the opaque continuation URL returned by Basalt.
```

Keep Handoff creation on your server. Never embed a `bhc_…` credential in browser JavaScript.
