Importing products

The /now flow uses public JSON import endpoints. Use these endpoints to preview a product architecture from a hosted JSON file or pasted JSON. Create the product after you accept the preview.

A raw Full Product Object (FPO) supports version values 1.0, 1.1, and 2.0. Runtype uses 2.0 by default. An FPO template supports top-level version values 1.0 and 1.1. Its nested productObject.version supports 1.0, 1.1, and 2.0.

At 2.0, an inline agent stores runtime fields under agent.config. At 1.0 and 1.1, it stores those fields on the agent object.

Supported sources

The import APIs accept these explicit JSON sources:

  • Agent-to-Agent (A2A) agent cards.
  • Raw FPO JSON.
  • FPO template JSON.

The import APIs reject these sources:

  • GitHub repository homepages.
  • README and Markdown URLs.
  • Raw JSON passed through query parameters.
  • Generic website or repository crawling.

Use GitHub URLs only for specific JSON files. The import service normalizes GitHub blob URLs to raw file URLs before fetching them. It accepts raw GitHub file URLs without conversion. For a gist, use a raw gist file URL that points to one JSON file.

Import flow

To import a product, follow these steps:

  1. Preview the source with POST /v1/quick-start/imports/preview.
  2. Reload the preview with GET /v1/quick-start/imports/:token.
  3. Create the product with POST /v1/quick-start/create.

The preview endpoints do not require authentication. Product creation requires authentication.

Step 1: Preview an import source

Choose a hosted URL or paste the JSON document into the request body.

Preview a hosted JSON document

To preview a public JSON file, send a URL source. The following TypeScript example sends the request:

TypeScript
1const previewResponse = await fetch('https://api.runtype.com/v1/quick-start/imports/preview', {
2 method: 'POST',
3 headers: {
4 'Content-Type': 'application/json',
5 },
6 body: JSON.stringify({
7 source: {
8 kind: 'url',
9 url: 'https://raw.githubusercontent.com/runtypelabs/core/main/docs/templates/quick-start/customer-support-fpo.json',
10 },
11 }),
12})
13
14const preview = await previewResponse.json()
15console.log(preview.importToken)
16console.log(preview.sourceType) // "fpo"
17console.log(preview.preview.productName)

The following cURL command sends the same request:

cURL
$curl https://api.runtype.com/v1/quick-start/imports/preview \
> -H "Content-Type: application/json" \
> -d '{
> "source": {
> "kind": "url",
> "url": "https://raw.githubusercontent.com/runtypelabs/core/main/docs/templates/quick-start/customer-support-fpo.json"
> }
> }'

Preview pasted JSON

To preview a document that you already have in memory, send a JSON source with its contents in content. The following TypeScript example reads a template file from your app and submits it:

TypeScript
1const templateDocument = await fetch('/YOUR_TEMPLATE_FILENAME.json').then((response) =>
2 response.text()
3)
4
5const previewResponse = await fetch('https://api.runtype.com/v1/quick-start/imports/preview', {
6 method: 'POST',
7 headers: {
8 'Content-Type': 'application/json',
9 },
10 body: JSON.stringify({
11 source: {
12 kind: 'json',
13 label: 'Customer Support Template',
14 content: templateDocument,
15 },
16 }),
17})
18
19const preview = await previewResponse.json()
20console.log(preview.sourceType) // "fpo-template"
21console.log(preview.template?.variables)

Replace YOUR_TEMPLATE_FILENAME with the filename that your app serves.

The following cURL command sends the template as a JSON string in content:

cURL
$curl https://api.runtype.com/v1/quick-start/imports/preview \
> -H "Content-Type: application/json" \
> -d @- <<'EOF'
${
> "source": {
> "kind": "json",
> "label": "Customer Support Template",
> "content": "{\"version\":\"1.0\",\"productObject\":{\"version\":\"1.0\",\"product\":{\"name\":\"{{productName}}\",\"description\":\"Support automation for {{companyName}}\"},\"capabilities\":[{\"id\":\"cap_support\",\"name\":\"Support Agent\",\"description\":\"Handle incoming support requests.\",\"agent\":{\"name\":\"{{productName}} Agent\",\"description\":\"Handle support requests for {{companyName}}.\",\"model\":\"claude-sonnet-4-5\"}}],\"tools\":[],\"surfaces\":[{\"id\":\"surface_chat\",\"name\":\"{{productName}} Chat\",\"type\":\"chat\",\"config\":{},\"routes\":[{\"capabilityId\":\"cap_support\"}]}],\"_meta\":{\"schemaVersion\":\"1.0\",\"catalogVersion\":\"1.0\",\"generatedAt\":\"2026-03-07T00:00:00.000Z\",\"generatorVersion\":\"1.0.0\",\"planHash\":\"import-json-example\"}},\"template\":{\"variables\":[{\"key\":\"productName\",\"label\":\"Product Name\",\"inputType\":\"text\",\"required\":true,\"defaultValue\":\"Example Organization Support Copilot\"},{\"key\":\"companyName\",\"label\":\"Company Name\",\"inputType\":\"text\",\"required\":true}]}}"
> }
>}
$EOF

The content string contains the productName and companyName template variables.

Step 2: Reload a preview session

The preview response includes an importToken. Use this token to restore the preview after an authentication redirect or page refresh.

The following TypeScript example restores the preview session:

TypeScript
1const session = await fetch(
2 'https://api.runtype.com/v1/quick-start/imports/qsi_YOUR_IMPORT_TOKEN'
3).then((response) => response.json())
4
5console.log(session.importToken)
6console.log(session.architecture)

Replace qsi_YOUR_IMPORT_TOKEN with the token returned by the preview request.

The following cURL command restores the same preview session:

cURL
$curl https://api.runtype.com/v1/quick-start/imports/qsi_YOUR_IMPORT_TOKEN

Preview sessions expire after 30 minutes. When the token does not identify a stored session, the API returns SESSION_NOT_FOUND.

Step 3: Create the product

Use the import token to create the product after you accept the preview.

Create a product from a raw FPO

To create a raw FPO import, send the importToken in a request that includes your API key. The following TypeScript example creates the product:

TypeScript
1const createResponse = await fetch('https://api.runtype.com/v1/quick-start/create', {
2 method: 'POST',
3 headers: {
4 Authorization: 'Bearer YOUR_API_KEY',
5 'Content-Type': 'application/json',
6 },
7 body: JSON.stringify({
8 importToken: 'qsi_YOUR_IMPORT_TOKEN',
9 }),
10})
11
12const created = await createResponse.json()
13console.log(created.redirectUrl)

Replace YOUR_API_KEY with your Runtype API key and qsi_YOUR_IMPORT_TOKEN with the preview token.

The following cURL command creates the same raw FPO import:

cURL
$curl https://api.runtype.com/v1/quick-start/create \
> -H "Authorization: Bearer YOUR_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "importToken": "qsi_YOUR_IMPORT_TOKEN"
> }'

Create a product from an FPO template

To create an FPO template import, send values for template variables that do not have defaults. The following TypeScript example sends the required values:

TypeScript
1const created = await fetch('https://api.runtype.com/v1/quick-start/create', {
2 method: 'POST',
3 headers: {
4 Authorization: 'Bearer YOUR_API_KEY',
5 'Content-Type': 'application/json',
6 },
7 body: JSON.stringify({
8 importToken: 'qsi_YOUR_TEMPLATE_IMPORT_TOKEN',
9 variables: {
10 companyName: 'Example Organization',
11 knowledgeBaseUrl: 'https://docs.example.com',
12 searchApiKey: process.env.FIRECRAWL_API_KEY,
13 },
14 }),
15}).then((response) => response.json())
16
17console.log(created.product.id)
18console.log(created.redirectUrl)

Replace YOUR_API_KEY with your Runtype API key, qsi_YOUR_TEMPLATE_IMPORT_TOKEN with the preview token, and YOUR_SEARCH_API_KEY with the secret for searchApiKey. Set FIRECRAWL_API_KEY to the same secret when you use the TypeScript example.

The following cURL command creates the same FPO template import:

cURL
$curl https://api.runtype.com/v1/quick-start/create \
> -H "Authorization: Bearer YOUR_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "importToken": "qsi_YOUR_TEMPLATE_IMPORT_TOKEN",
> "variables": {
> "companyName": "Example Organization",
> "knowledgeBaseUrl": "https://docs.example.com",
> "searchApiKey": "YOUR_SEARCH_API_KEY"
> }
> }'

The importer uses secret template values to resolve the final product object. It omits those values from preview payloads, quick-start provenance metadata, and the create response.

Create a repository button

To add a repository button labeled Deploy to Runtype, link directly to a hosted JSON document. The following Markdown snippet creates the button:

1[![Deploy to Runtype](https://runtype.com/badge.svg)](https://use.runtype.com/now?from=https%3A%2F%2Fraw.githubusercontent.com%2Fruntypelabs%2Fcore%2Fmain%2Fdocs%2Ftemplates%2Fquick-start%2Fcustomer-support-fpo.json)

The example files in this guide are:

  • docs/templates/quick-start/customer-support-fpo.json.
  • docs/templates/quick-start/customer-support-fpo-template.json.
  • docs/templates/quick-start/deploy-to-runtype.md.

Next steps

  • FPO templates: define reusable product templates with user-provided values.
  • Quickstart: make your first Runtype API call.