Managing records programmatically
Create, update, edit in bulk, delete, import, and export Records from code with the Runtype API, the TypeScript SDK, the runtype CLI, or the Runtype MCP server. For the same tasks on the Records page in the dashboard, see Creating and managing records.
Before you begin
Make sure that you have the following:
- A Runtype API key with the Records (Full) permission. A key with only Records (Read) can list, get, and export Records, and write requests return
403. For more information, see Managing API keys. - Optional: the
runtypeCLI, signed in withruntype login. For setup, see Authentication.
The examples read your API key from the RUNTYPE_API_KEY environment variable:
Replace YOUR_API_KEY with your Runtype API key. The TypeScript examples use this client:
The following table shows which interface supports each operation:
Create a Record
Send a type, a name, and an optional metadata object. The following examples create a customer Record:
cURL
TypeScript
CLI
The API returns 201 with the created Record, including its id. Save the ID to update or delete the Record later.
The same write rules apply as in the dashboard:
- Each combination of type and name is unique. A duplicate returns
409. - Runtype converts top-level metadata keys to lowercase snake_case. The response includes a
warningsarray that lists each renamed key. - Metadata that violates a Record type schema in
enforcemode returns422. For more information, see Defining a schema for a record type.
List and get Records
To list Records, send GET /v1/records. Filter by type, and page through results with limit and cursor. limit accepts 1 to 100 and defaults to 25. The response includes pagination.nextCursor when more Records exist. The following examples list the first 100 customer Records:
cURL
TypeScript
CLI
To get one Record with its full metadata, send GET /v1/records/RECORD_ID, call client.records.get(RECORD_ID), or run runtype records get <record-id>. Replace RECORD_ID or <record-id> with the Record ID.
To select Records by metadata values, pass a record filter. For the filter syntax, see Filtering and searching records.
Update a Record
Send only the fields that you want to change: name, type, metadata, or ownerId. Fields that you omit keep their values.
An update that includes metadata replaces the whole metadata object. Include every metadata field that you want to keep. An update that omits metadata leaves it unchanged. To change a few fields and keep the rest, use a bulk edit with the Record ID instead.
The following examples change the tier field of one Record and keep its email field:
cURL
TypeScript
CLI
Replace RECORD_ID or <record-id> with the Record ID. A change of name or type that matches another Record returns 409 with duplicate_record. An update that replaces metadata or changes type returns 409 with record_conflict if another request changed the Record’s metadata or type while the update was applied. The update changes nothing. Get the Record again and retry.
Edit Records in bulk
A bulk edit sets or removes metadata fields on many Records in one request, and keeps the fields that you don’t name. Choose the Records with one of the following targets:
recordIds: an array of Record IDs.recordFilter: a record filter object. It matches Records of one type.applyToAll:trueto edit every Record in your account.
Then describe the change with updates, deleteFields, or both. updates sets each named field to a value. deleteFields removes each named field. Both accept dot notation for nested fields, such as address.city. Bulk edit doesn’t change names or types.
Set dryRun to true to preview the edit without saving it. The response lists each affected Record with the before and after values of the changed fields. The following examples preview an upgrade of every standard customer to premium:
cURL
TypeScript
CLI
To apply the edit, send the same request with dryRun set to false. The response recordIds array lists the edited Records.
A bulk edit is all or nothing. If the result for any Record breaks a metadata limit or a Record type schema in enforce mode, the API rejects the whole edit and changes no Records. If another request changes the metadata or type of a target Record while the edit is applied, the API returns 409 with record_conflict and changes no Records. Send the edit again.
With applyToAll set to true and no other target, the edit changes every Record in your account. Run it with dryRun first.
Delete Records
To delete one Record, send DELETE /v1/records/RECORD_ID, call client.records.delete(RECORD_ID), or run runtype records delete <record-id>. The API returns 204. In a terminal, the CLI asks you to confirm the delete.
To delete many Records, send their IDs to the bulk delete endpoint:
cURL
TypeScript
CLI
Replace RECORD_ID_1 and RECORD_ID_2 with Record IDs. The response reports deleted, the deletedIds, and any notFoundIds. An ID that doesn’t match a Record in your account appears in notFoundIds. An ID in the wrong format rejects the whole request with 400.
Deletes through the API, SDK, CLI, and MCP server are permanent and offer no undo.
Import Records from a CSV file
Upload a CSV file as multipart/form-data to create one Record for each row. The request takes the following fields:
file: the CSV file. It needs a header row and at least one data row.nameColumn: the column that holds each Record name. The default isname.typeColumn: the column that holds each Record type. The default istype.typeValue: one type for every row. When you sendtypeValue, the API ignorestypeColumn.
Column names match regardless of letter case. The following examples import a file of customers without a type column:
cURL
TypeScript
The import stores every column as a metadata field, as the dashboard import does. An import can partly succeed. The API returns 201 with created (the number of Records created), errors (the number of rows that failed), and errorDetails (one message for each failed row, with its row number). Check errors before you treat the import as complete. For the reasons a row fails, see Import Records from a CSV file.
If the file has no rows, or a named column isn’t in the header, the API returns 400 and creates no Records.
Export Records as CSV
To download matching Records as a CSV file, send GET /v1/records/export. It accepts the same type, search, ownerId, and recordFilter query parameters as the list endpoint, and it returns every matching Record in one file. The following request saves every customer Record to customers.csv:
The file has the columns id, type, name, ownerId, createdAt, and updatedAt, then one column for each metadata field. The X-Record-Count response header holds the number of exported Records. If no Records match, the API returns 204 with no body.
The runtype records export command writes a single page of Records to a JSON or CSV file. It exports up to 100 Records, and a --limit value greater than 100 fails. Its CSV format puts all metadata in one JSON column. To export more than 100 Records, use the API endpoint.
Manage Records with the MCP server
The Runtype MCP server provides these tools for Records: list_records, get_record, create_record, update_record, delete_record, bulk_edit_records, and bulk_delete_records. The tools take snake_case arguments, such as record_ids, record_filter, delete_fields, and dry_run. bulk_edit_records requires dry_run, so a client states whether each call is a preview. Like the API, update_record replaces the whole metadata object when you send metadata. The MCP server has no tools for CSV import or export. For setup, see Runtype MCP server.
Troubleshoot Record requests
The following table lists common errors and how to fix them:
Next steps
- Creating and managing records: manage Records on the Records page.
- Filtering and searching records: write the record filters that list, export, and bulk edit use.
- Defining a schema for a record type: validate metadata on every write.
- Using records in flows: read and write Records from a Flow.
- Create record: review every request and response field in the API reference.