http://localhost:3333/api/kiwi.
A typical import has three steps:
1
Browse
For databases, list tables or collections with
POST /import/browse.2
Preview
Render sample pages with
POST /import/preview and get suggested field mappings from POST /import/infer-fields. Nothing is written.3
Import
Send the same body to
POST /import. The server saves the connection (without secrets) so you can re-run it later.Run an import
Import records from a source and write one markdown page per record.POST /api/kiwi/import
from selects the source. The other fields depend on the source (see Sources). /import/preview and /import/infer-fields accept the same body.
string
required
Source type, for example
postgres, csv, or obsidian.string
Directory on the server to read from. Required for
markdown and obsidian.string
File on the server to read from. Required for
csv, json, jsonl, and bibtex. Also accepted by croissant.string
Croissant metadata URL, as an alternative to
file.string
Connection string for
postgres and mysql. Also accepted as the URI for mongodb.string
Connection URI for
mongodb.string
SQLite database file path. Required for
sqlite.string
Table to import from
postgres, mysql, or sqlite. SQL sources need either table or query.string
SQL query to run instead of reading a whole table.
string
Database name. Required for
mongodb.string
Collection name. Required for
mongodb and firestore.string
Google Cloud project ID. Required for
firestore.object
Service account JSON for
firestore. Never stored.string
Notion database ID. Required for
notion.string
Airtable base ID. Required for
airtable.string
Airtable table ID. Required for
airtable.string
API key for
notion or airtable. Falls back to the NOTION_API_KEY or AIRTABLE_API_KEY environment variable. Never stored.string
Directory to write pages into. Defaults to the source name.
string
Field used as the page filename. Defaults to the source’s primary key.
string[]
Only keep these fields in frontmatter.
object[]
Rename, retype, or skip fields. Each entry is
{"source", "target", "type", "skip"}, where type is string, number, boolean, or date. When you send any mapping, unmapped fields are dropped.boolean
default:"false"
Count what would be written without writing anything.
integer
default:"0"
Stop after this many records.
0 means no limit.string
Force a connector path:
builtin, airbyte (local Docker), or airbyte-cloud. Leave empty to pick automatically.object
Raw Airbyte connector config. Sending it routes the import through Airbyte.
string
Override the Airbyte Docker image.
string[]
Airbyte streams to sync. Defaults to all streams.
string
default:"api-import"
Git commit author for the imported pages.
integer
Pages created or updated.
integer
Records whose page was already up to date.
integer
Pages marked with
_archived_at because their source row disappeared. Omitted when zero.string[]
Per-record error messages.
Response
400 when from or a required source field is missing or the source type is unknown, and 500 when the import fails.
path, file, and db are paths on the server’s filesystem. To import a file from your own machine, use POST /import/upload.postgres, mysql, mongodb, firestore, notion, airtable, firebase-rtdb), a run without dry_run or limit is a full sync: pages whose source rows no longer exist are archived. A successful import also saves its settings as a connection and turns on hourly auto-sync for syncable sources.
Sources
For Excel and YAML files, use the
kiwifs import CLI. See Import overview for source-specific guides.
Upload a file and import it
Upload a local file and import, preview, or infer fields from it in one request.POST /api/kiwi/import/upload (multipart/form-data)
file
required
The data file. Maximum 256 MB.
string
required
One of
csv, json, jsonl, bibtex, or sqlite. Excel and YAML uploads are accepted by the form but not yet imported; use the kiwifs import CLI for those.string
default:"import"
import writes pages, preview returns the first 5 rendered records, and infer-fields returns suggested field mappings.string
Target directory. Defaults to the uploaded filename without its extension.
string
Field used as the page filename.
string
Field mappings as a JSON-encoded array, in the same shape as
POST /import.string
Table name for
sqlite. A sqlite upload needs either table or query.string
SQL query for
sqlite.mode: the import response, the preview response, or the infer-fields response. Returns 400 for an unsupported from and 413 when the file is over 256 MB.
List sources
List the source types this server can import from, and whether Airbyte connectors are available.GET /api/kiwi/import/sources
string[]
Sources handled natively by KiwiFS.
string[] | null
Airbyte connector sources.
null when neither Docker nor an Airbyte Cloud key is available.boolean
Whether a Docker daemon is reachable for local Airbyte connectors.
boolean
Whether an Airbyte Cloud API key is configured.
Response
Browse tables and collections
List the tables or collections in a database before you import.POST /api/kiwi/import/browse
string
required
postgres, mysql, mongodb, or firestore.string
Connection string for
postgres and mysql.string
Connection URI for
mongodb. dsn also works.string
Database name. Required for
mongodb.string
Project ID. Required for
firestore.object
Service account JSON for
firestore.object[]
Response
400 for other source types or when the connection fails.
Preview an import
Render the first few records as pages without writing anything.POST /api/kiwi/import/preview
Takes the same body as POST /import, including path for markdown and obsidian and query for SQL sources, plus:
integer
default:"5"
Number of records to preview. Values outside 1–20 fall back to 5.
object[]
Response
Infer field mappings
Sample up to 100 records and suggest a field mapping with detected types.POST /api/kiwi/import/infer-fields
Takes the same body as POST /import/preview, including path and query. prefix, columns, field_mappings, and limit are ignored.
object[]
Response
_ are left out. Edit the result as needed and pass it as field_mappings to preview or import.
Saved connections
A connection is the non-secret part of an import: source, table, prefix, columns, and sync settings. KiwiFS saves one automatically after each successfulPOST /import (one per source and prefix) and keeps them in .kiwi/state/imports.json. Credentials and API keys are never stored, so you send them again when you re-run a connection that needs them.
Connection object
string
Connection ID (UUID).
string
Source type.
string
Display name, for example
postgres:articles.string
Target directory.
various
Source settings, as sent on import.
string
RFC 3339 time of the last run.
object
imported, skipped, archived, and errors from the last run.string
RFC 3339 creation time.
boolean
Whether auto-sync is on.
string
Go duration such as
5m, 1h, or 24h.string
RFC 3339 time of the next scheduled sync.
string
idle, running, or error.string
Last sync error, if any.
various
Airbyte settings, when the import ran through Airbyte.
List connections
List saved import connections.GET /api/kiwi/import/connections
[] when the connection store is unavailable.
Response
Save a connection
Create or update a connection without running an import.POST /api/kiwi/import/connections
The body is a connection object. from is required, and name defaults to from. Include id to update an existing connection or omit it to create one.
200 with the saved connection, including its id. Returns 400 without from and 503 when the connection store is unavailable.
Delete a connection
Remove a saved connection. Pages it imported are not touched.DELETE /api/kiwi/import/connections/:id
204 on success and 404 for an unknown ID.
Run a connection
Re-run a saved connection’s import.POST /api/kiwi/import/connections/:id/run
string
required
Connection ID.
object
Service account JSON for this run only (
firestore).string
API key for this run only (
notion, airtable).POST /import and updates last_run and last_stats. Returns 404 for an unknown ID.
Configure auto-sync
Turn auto-sync on or off for a connection, or change its interval.POST /api/kiwi/import/connections/:id/sync
string
required
Connection ID.
boolean
Turn auto-sync on or off. Omit to keep the current state.
string
Go duration such as
15m, 1h, or 24h. Invalid values fall back to 1h.next_sync rescheduled. Returns 404 for an unknown ID.
Scheduled syncs run without credentials, so they only work for sources that don’t need any at run time, such as a
postgres DSN that includes its password.Sync status
List every connection with auto-sync enabled.GET /api/kiwi/import/sync/status
sync_enabled is true. Check sync_status and sync_error for failures.
Airbyte endpoints
Configure Airbyte connectors, locally through Docker or through Airbyte Cloud. Airbyte Cloud needsairbyte_api_key and airbyte_workspace_id under [import] in .kiwi/config.toml, or the AIRBYTE_API_KEY and AIRBYTE_WORKSPACE_ID environment variables.
The local endpoints return
503 when Docker is not running. The Cloud endpoints return 503 without an API key and 502 when Airbyte Cloud rejects the request.
Ingest a document
Convert a PDF, Office file, image, or other document to markdown and write it as one or more pages.POST /api/kiwi/ingest
string
required
Path to the file on the server. Supported extensions:
pdf, docx, pptx, xlsx, html, htm, csv, json, xml, epub, jpg, jpeg, png, gif, bmp, tiff, mp3, wav, m4a, zip.string
default:"single"
single writes one page. sections writes one page per heading when the document has more than one section.string
Directory for the output pages. Defaults to
imports/<file-name-slug>/.boolean
default:"false"
Extract keywords for each section.
integer
default:"10"
Keywords to extract per section.
boolean
default:"false"
Turn references like “see Section 2.1” into wiki links.
string
default:"kiwi-ingest"
Git commit author.
string
The input file.
string
Detected input format.
integer
Sections found in the converted document.
string[]
Pages written.
string[]
Extracted keywords, when requested.
Response
400 for a missing file or an unsupported extension.
Export pages
Stream every markdown page, or the pages under a path, as JSONL, CSV, or Parquet.GET /api/kiwi/export
string
default:"jsonl"
jsonl, csv, or parquet.string
Only export pages whose path starts with this prefix, for example
concepts/.string
Comma-separated frontmatter fields to use as CSV columns. Without it, columns are detected from the first page.
boolean
default:"false"
Include the full markdown file in
content.boolean
default:"false"
Include outgoing (
links_out) and incoming (links_in) wiki links.boolean
default:"false"
Include vector chunks. Not supported with
parquet.integer
default:"0"
Maximum pages to export.
0 means no limit.Content-Type set to application/x-ndjson, text/csv, or application/vnd.apache.parquet. Each JSONL line is one page:
string
Page path.
object
Parsed frontmatter.
integer
Words in the body.
string
Full file, with
include_content=true.string[]
Outgoing wiki links, with
include_links=true.string[]
Pages linking here, with
include_links=true.object[]
chunk_idx, text, and vector for each chunk, with include_embeddings=true.concepts.jsonl
path column:
pages.csv
400 for an unknown format, a negative limit, or include_embeddings with parquet.
Export a document
Render a page or folder to PDF, HTML, slides, or a static site and download the result.POST /api/kiwi/export/document
string
required
pdf, html, slides, or site.string
required
File or directory to render.
Content-Disposition: attachment header. Rendering times out after 5 minutes. See Document export for theme, bibliography, slide, and site options.
Related
Import overview
Source guides and the
kiwifs import CLI.Saved connections
Re-running imports and auto-sync.
Airbyte import
Docker and Airbyte Cloud connectors.
Export overview
Formats and when to use each.