# Data ## Add data **post** `/v1/data/{namespace}` Add data to a namespace, returning immediately. Processing happens asynchronously in the background. ### Path Parameters - `namespace: string` The namespace to ingest data into ### Body Parameters - `data: object { id } or array of object { id }` A data object to ingest. It must include an id field. All other fields are flexible and can be any JSON type. - `DataObject object { id }` A data object to ingest. It must include an id field. All other fields are flexible and can be any JSON type. - `id: string` Unique identifier for this data object. This should be a meaningful identifier in the customer's system, as it is the main way to search for specific items between systems. - `DataObjectArray = array of object { id }` Array of data objects to ingest. - `id: string` Unique identifier for this data object. This should be a meaningful identifier in the customer's system, as it is the main way to search for specific items between systems. ### Returns - `requestId: string` Unique identifier for tracking this request. Data processing happens asynchronously after this response. - `status: "accepted"` Request was accepted for processing - `"accepted"` ### Example ```http curl https://api.safetykit.com/v1/data/$NAMESPACE \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $SAFETYKIT_API_KEY" \ -d '{ "data": { "id": "user-12345" } }' ``` #### Response ```json { "requestId": "req_01h2m7qdmdjckc30e1mnq6xqfd", "status": "accepted" } ``` ## Add large batch of data **post** `/v1/data/{namespace}/import` Request a pre-signed upload URL for importing large JSONL batches into a namespace. After receiving `upload_url`, upload your JSONL file using `PUT {upload_url}` with header `Content-Type: application/json`; put each JSON object on a new line. ### Path Parameters - `namespace: string` The namespace to ingest data into ### Returns - `expires_at: string` ISO timestamp when upload_url expires (12 hours after issuance) - `objectKey: string` S3 object key where uploaded JSONL will be processed from - `requestId: string` Unique identifier for this import request - `status: "pending_upload"` Import request is waiting for file upload - `"pending_upload"` - `upload_url: string` Pre-signed upload URL for PUT-ing JSONL content (`Content-Type: application/json`) ### Example ```http curl https://api.safetykit.com/v1/data/$NAMESPACE/import \ -X POST \ -H "Authorization: Bearer $SAFETYKIT_API_KEY" ``` #### Response ```json { "expires_at": "2026-01-15T12:30:00.000Z", "objectKey": "TEAM_ID/data-api-request-input/products/request_01K....jsonl", "requestId": "req_01h2m7qdmdjckc30e1mnq6xqfd", "status": "pending_upload", "upload_url": "https://s3.amazonaws.com/..." } ``` ## Get request status **get** `/v1/data/{namespace}/requests/{requestId}` Retrieve the status of a data ingestion request. Works for both add and import requests. ### Path Parameters - `namespace: string` The namespace the data was ingested into - `requestId: string` The request ID returned from the Add endpoint ### Returns - `DataGetRequestAddOutput object { data, namespace, request_id, status }` - `data: array of object { id, output, url, metadata }` - `id: string` Object identifier from the ingested data - `output: object { actions, fields, labels }` - `actions: array of unknown` - `fields: map[unknown]` - `labels: array of object { label }` - `label: string` - `url: string` - `metadata: optional map[unknown]` - `namespace: string` - `request_id: string` - `status: "queued" or "uploading" or "ingesting" or 2 more` - `"queued"` - `"uploading"` - `"ingesting"` - `"succeeded"` - `"failed"` - `DataGetRequestImportOutput object { data_count, data_expires_at, data_url, 3 more }` - `data_count: number` - `data_expires_at: string` - `data_url: string` - `namespace: string` - `request_id: string` - `status: "queued" or "uploading" or "ingesting" or 2 more` - `"queued"` - `"uploading"` - `"ingesting"` - `"succeeded"` - `"failed"` ### Example ```http curl https://api.safetykit.com/v1/data/$NAMESPACE/requests/$REQUEST_ID \ -H "Authorization: Bearer $SAFETYKIT_API_KEY" ``` #### Response ```json { "data": [ { "id": "item-001", "output": { "actions": [ {} ], "fields": {}, "labels": [ { "label": "illegal_drugs.violation" }, { "label": "hazardous.violation" } ] }, "url": "https://app.safetykit.com/...", "metadata": { "internal-ref": "bar" } } ], "namespace": "products", "request_id": "request_01KHSKHQSYJN4A5P7RRVEXHWE9", "status": "succeeded" } ``` ## Update namespace settings **put** `/v1/data/{namespace}/settings` Create or replace settings for a namespace, primarily used to change the schema associated with the namespace. ### Path Parameters - `namespace: string` The namespace to ingest data into ### Body Parameters - `schema: map[object { content_type, display_hint, field_limit, namespace_ref } ]` Schema mapping field names to their definitions. Use content_type to specify which fields contain URLs that should be processed (images, videos, or websites), datetime fields, or 'metadata' for fields that should be stored but not indexed. Use display_hint to provide UI rendering hints. - `content_type: optional "image_url" or "video_url" or "website_url" or 2 more` The type of content (image_url, video_url, website_url, datetime, or metadata). When specified as a URL type, SafetyKit will process the URL. Use 'metadata' for fields that should be stored but not indexed. - `"image_url"` - `"video_url"` - `"website_url"` - `"datetime"` - `"metadata"` - `display_hint: optional object { type }` Display hint for UI rendering of this field - `type: "title" or "subtitle" or "description" or 13 more` The display hint type - `"title"` - `"subtitle"` - `"description"` - `"primary_image_url"` - `"video_url"` - `"location"` - `"compact_text"` - `"markdown"` - `"html"` - `"email.reply_to"` - `"email.body"` - `"email.subject"` - `"email.body_image"` - `"email.logo_image"` - `"email.event"` - `"email.footer"` - `field_limit: optional number` Maximum amount of this field to include when sending to AI models. For text fields, this is the character limit. For array fields (e.g. image URLs), this is the maximum number of items. - `namespace_ref: optional string` The namespace which an id refers to, creating a parent-child relationship with that namespace. ### Returns - `namespace: string` - `status: "updated"` - `"updated"` ### Example ```http curl https://api.safetykit.com/v1/data/$NAMESPACE/settings \ -X PUT \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $SAFETYKIT_API_KEY" \ -d '{ "schema": { "profile_image": { "content_type": "image_url" }, "cover_photo": { "content_type": "image_url" }, "website": { "content_type": "website_url" } } }' ``` #### Response ```json { "namespace": "users", "status": "updated" } ``` ## Domain Types ### Data Add Response - `DataAddResponse object { requestId, status }` Response confirming data was accepted for asynchronous processing. The requestId can be used for debugging and tracking. - `requestId: string` Unique identifier for tracking this request. Data processing happens asynchronously after this response. - `status: "accepted"` Request was accepted for processing - `"accepted"` ### Data Import Response - `DataImportResponse object { expires_at, objectKey, requestId, 2 more }` Response containing an upload URL and metadata for large-batch import processing. Use `PUT {upload_url}` to upload JSONL (one JSON object per line). `upload_url` expires in 12 hours. - `expires_at: string` ISO timestamp when upload_url expires (12 hours after issuance) - `objectKey: string` S3 object key where uploaded JSONL will be processed from - `requestId: string` Unique identifier for this import request - `status: "pending_upload"` Import request is waiting for file upload - `"pending_upload"` - `upload_url: string` Pre-signed upload URL for PUT-ing JSONL content (`Content-Type: application/json`) ### Data Get Status Response - `DataGetStatusResponse = object { data, namespace, request_id, status } or object { data_count, data_expires_at, data_url, 3 more }` Response containing request status and processed output data. - `DataGetRequestAddOutput object { data, namespace, request_id, status }` - `data: array of object { id, output, url, metadata }` - `id: string` Object identifier from the ingested data - `output: object { actions, fields, labels }` - `actions: array of unknown` - `fields: map[unknown]` - `labels: array of object { label }` - `label: string` - `url: string` - `metadata: optional map[unknown]` - `namespace: string` - `request_id: string` - `status: "queued" or "uploading" or "ingesting" or 2 more` - `"queued"` - `"uploading"` - `"ingesting"` - `"succeeded"` - `"failed"` - `DataGetRequestImportOutput object { data_count, data_expires_at, data_url, 3 more }` - `data_count: number` - `data_expires_at: string` - `data_url: string` - `namespace: string` - `request_id: string` - `status: "queued" or "uploading" or "ingesting" or 2 more` - `"queued"` - `"uploading"` - `"ingesting"` - `"succeeded"` - `"failed"` ### Data Update Settings Response - `DataUpdateSettingsResponse object { namespace, status }` Namespace configuration was stored. - `namespace: string` - `status: "updated"` - `"updated"`