Copy-and-Paste Quickstart
Copy-paste starter snippets for ingest, upload URLs, polling, and webhooks.
Ingest object(s)
Section titled “Ingest object(s)”import Safetykit from "safetykit";
const client = new Safetykit({ apiKey: process.env.SAFETYKIT_API_KEY });
const response = await client.data.ingest("messages", { data: [ { id: "message_12345", user_id: "user_67890", text: "sample content", }, ],});
console.log(response.requestId);from safetykit import Safetykit
client = Safetykit(api_key="sk_your_api_key")
response = client.data.ingest("messages", { "data": [ { "id": "message_12345", "user_id": "user_67890", "text": "sample content" } ]})
print(response.request_id)import kotlinx.serialization.json.Jsonimport kotlinx.serialization.json.jsonObjectimport kotlinx.serialization.json.jsonPrimitiveimport java.net.URIimport java.net.http.HttpClientimport java.net.http.HttpRequestimport java.net.http.HttpResponse
val client = HttpClient.newHttpClient()val apiKey = System.getenv("SAFETYKIT_API_KEY")val namespace = "messages"
val body = """ { "data": [ { "id": "message_12345", "user_id": "user_67890", "text": "sample content" } ] }""".trimIndent()
val request = HttpRequest.newBuilder() .uri(URI.create("https://api.safetykit.com/v1/data/$namespace")) .header("Authorization", "Bearer $apiKey") .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(body)) .build()
val response = client.send(request, HttpResponse.BodyHandlers.ofString())println(response.body())import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();String apiKey = System.getenv("SAFETYKIT_API_KEY");String namespace = "messages";
String body = """ { "data": [ { "id": "message_12345", "user_id": "user_67890", "text": "sample content" } ] } """;
HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://api.safetykit.com/v1/data/" + namespace)) .header("Authorization", "Bearer " + apiKey) .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(body)) .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());System.out.println(response.body());API_KEY="sk_your_api_key"NAMESPACE="messages"
curl -X POST "https://api.safetykit.com/v1/data/${NAMESPACE}" \ -H "Authorization: Bearer ${API_KEY}" \ -H "Content-Type: application/json" \ -d '{ "data": [ { "id": "message_12345", "user_id": "user_67890", "text": "sample content" } ] }'API reference: POST /v1/data/{namespace}
Upload URL flow
Section titled “Upload URL flow”const uploadResponse = await client.data.createUploadUrl("messages", {});
await fetch(uploadResponse.upload_url, { method: "PUT", headers: { "Content-Type": "application/json" }, body: `{"id":"message_12345","text":"sample content"}\n{"id":"message_12346","text":"another message"}\n`,});
console.log(uploadResponse.requestId);import requests
upload_response = client.data.create_upload_url("messages", {})
jsonl_payload = ( '{"id":"message_12345","text":"sample content"}\n' '{"id":"message_12346","text":"another message"}\n')
requests.put( upload_response.upload_url, data=jsonl_payload.encode("utf-8"), headers={"Content-Type": "application/json"},)
print(upload_response.request_id)import kotlinx.serialization.json.Jsonimport kotlinx.serialization.json.jsonObjectimport kotlinx.serialization.json.jsonPrimitiveimport java.net.URIimport java.net.http.HttpClientimport java.net.http.HttpRequestimport java.net.http.HttpResponse
val client = HttpClient.newHttpClient()val apiKey = System.getenv("SAFETYKIT_API_KEY")val namespace = "messages"
val uploadUrlRequest = HttpRequest.newBuilder() .uri(URI.create("https://api.safetykit.com/v1/data/$namespace/requests/upload-url")) .header("Authorization", "Bearer $apiKey") .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString("{}")) .build()
val uploadResponse = client.send(uploadUrlRequest, HttpResponse.BodyHandlers.ofString())val uploadResponseJson = Json.parseToJsonElement(uploadResponse.body()).jsonObjectval uploadUrl = uploadResponseJson["upload_url"]!!.jsonPrimitive.content
val jsonlPayload = """ {"id":"message_12345","text":"sample content"} {"id":"message_12346","text":"another message"}
""".trimIndent()
val putRequest = HttpRequest.newBuilder() .uri(URI.create(uploadUrl)) .header("Content-Type", "application/json") .PUT(HttpRequest.BodyPublishers.ofString(jsonlPayload)) .build()
client.send(putRequest, HttpResponse.BodyHandlers.discarding())println(uploadResponseJson["requestId"]!!.jsonPrimitive.content)import com.fasterxml.jackson.databind.JsonNode;import com.fasterxml.jackson.databind.ObjectMapper;import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();ObjectMapper objectMapper = new ObjectMapper();String apiKey = System.getenv("SAFETYKIT_API_KEY");String namespace = "messages";
HttpRequest uploadUrlRequest = HttpRequest.newBuilder() .uri(URI.create("https://api.safetykit.com/v1/data/" + namespace + "/requests/upload-url")) .header("Authorization", "Bearer " + apiKey) .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString("{}")) .build();
HttpResponse<String> uploadResponse = client.send(uploadUrlRequest, HttpResponse.BodyHandlers.ofString());JsonNode uploadResponseJson = objectMapper.readTree(uploadResponse.body());String uploadUrl = uploadResponseJson.get("upload_url").asText();
String jsonlPayload = """ {"id":"message_12345","text":"sample content"} {"id":"message_12346","text":"another message"} """;
HttpRequest putRequest = HttpRequest.newBuilder() .uri(URI.create(uploadUrl)) .header("Content-Type", "application/json") .PUT(HttpRequest.BodyPublishers.ofString(jsonlPayload)) .build();
client.send(putRequest, HttpResponse.BodyHandlers.discarding());System.out.println(uploadResponseJson.get("requestId").asText());API_KEY="sk_your_api_key"NAMESPACE="messages"
UPLOAD_RESPONSE="$(curl -sS -X POST "https://api.safetykit.com/v1/data/${NAMESPACE}/requests/upload-url" \ -H "Authorization: Bearer ${API_KEY}" \ -H "Content-Type: application/json" \ -d '{}')"
UPLOAD_URL="$(printf '%s' "$UPLOAD_RESPONSE" | jq -r '.upload_url')"REQUEST_ID="$(printf '%s' "$UPLOAD_RESPONSE" | jq -r '.requestId')"
curl -X PUT "$UPLOAD_URL" \ -H "Content-Type: application/json" \ --data-binary @data.jsonl
echo "Upload request created: ${REQUEST_ID}"API reference: POST /v1/data/{namespace}/requests/upload-url
Poll request status
Section titled “Poll request status”async function waitForCompletion(namespace: string, requestId: string) { while (true) { const status = await client.data.getStatus(namespace, requestId); if (status.status === "succeeded" || status.status === "failed") { return status; } await new Promise((resolve) => setTimeout(resolve, 5000)); }}import time
def wait_for_completion(namespace: str, request_id: str): while True: status = client.data.get_status(namespace, request_id) if status.status in ("succeeded", "failed"): return status time.sleep(5)import kotlinx.serialization.json.Jsonimport kotlinx.serialization.json.jsonObjectimport kotlinx.serialization.json.jsonPrimitiveimport java.net.URIimport java.net.http.HttpClientimport java.net.http.HttpRequestimport java.net.http.HttpResponse
fun waitForCompletion(namespace: String, requestId: String): String { val client = HttpClient.newHttpClient() val apiKey = System.getenv("SAFETYKIT_API_KEY")
while (true) { val request = HttpRequest.newBuilder() .uri(URI.create("https://api.safetykit.com/v1/data/$namespace/requests/$requestId")) .header("Authorization", "Bearer $apiKey") .GET() .build()
val response = client.send(request, HttpResponse.BodyHandlers.ofString()) val status = Json.parseToJsonElement(response.body()) .jsonObject["status"]!! .jsonPrimitive.content
if (status == "succeeded" || status == "failed") { return response.body() } Thread.sleep(5_000) }}import com.fasterxml.jackson.databind.JsonNode;import com.fasterxml.jackson.databind.ObjectMapper;import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;
String waitForCompletion(String namespace, String requestId) throws Exception { HttpClient client = HttpClient.newHttpClient(); ObjectMapper objectMapper = new ObjectMapper(); String apiKey = System.getenv("SAFETYKIT_API_KEY");
while (true) { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://api.safetykit.com/v1/data/" + namespace + "/requests/" + requestId)) .header("Authorization", "Bearer " + apiKey) .GET() .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); JsonNode statusResponse = objectMapper.readTree(response.body()); String status = statusResponse.get("status").asText();
if (status.equals("succeeded") || status.equals("failed")) { return response.body(); } Thread.sleep(5_000); }}API reference: GET /v1/data/{namespace}/requests/{requestId}
If the completed request output exceeds the 5 MiB inline response limit, use GET /v1/data/{namespace}/requests/{requestId}/results/download-url to retrieve a temporary S3 URL for the full result file.
Verify webhook signature
Section titled “Verify webhook signature”import { Webhook } from "svix";
const verifier = new Webhook(process.env.SAFETYKIT_WEBHOOK_SECRET!);
const payload = verifier.verify(rawBody, { "webhook-id": req.headers["webhook-id"] as string, "webhook-timestamp": req.headers["webhook-timestamp"] as string, "webhook-signature": req.headers["webhook-signature"] as string,});from svix.webhooks import Webhook
verifier = Webhook("whsec_your_signing_secret")payload = verifier.verify(raw_body, request_headers)import com.svix.Webhookimport java.net.http.HttpHeaders
val verifier = Webhook("whsec_your_signing_secret")val payload = verifier.verify(rawBody, requestHeaders)import com.svix.Webhook;import java.net.http.HttpHeaders;
Webhook verifier = new Webhook("whsec_your_signing_secret");Object payload = verifier.verify(rawBody, requestHeaders);API reference: Verifying Signatures
Handle workflow completion event
Section titled “Handle workflow completion event”if (event.type === "workflow.succeeded" && event.namespace === "messages") { const { id, output } = event; await handleReviewDecision(id, output);}API reference: workflow.succeeded event