curl --request POST \
--url https://api.runpulse.com/split \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"extraction_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"split_config_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"async": false
}
'import requests
url = "https://api.runpulse.com/split"
payload = {
"extraction_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"split_config_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"async": False
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
extraction_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
split_config_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
async: false
})
};
fetch('https://api.runpulse.com/split', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.runpulse.com/split",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'extraction_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'split_config_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'async' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.runpulse.com/split"
payload := strings.NewReader("{\n \"extraction_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"split_config_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"async\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.runpulse.com/split")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"extraction_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"split_config_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"async\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.runpulse.com/split")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"extraction_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"split_config_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"async\": false\n}"
response = http.request(request)
puts response.read_body{
"split_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"split_output": {
"splits": {}
},
"credits_used": 123,
"plan_info": {
"tier": "<string>",
"total_credits_used": 123,
"pages_used": 1,
"note": "<string>"
}
}{
"job_id": "<string>",
"status": "pending",
"message": "<string>",
"queuedAt": "2023-11-07T05:31:56Z",
"credits_used": 123
}Split Document
Identify which pages of a document contain each topic/section. Takes an existing extraction and a list of topics, then uses AI to identify which PDF pages contain content related to each topic.
The result is persisted with a split_id that can be used with
the /schema endpoint (split mode) for targeted schema extraction on
specific page groups.
Set async: true to return immediately with a job_id for polling.
To split many extractions at once, see Batch Split or the Batch Processing guide.
curl --request POST \
--url https://api.runpulse.com/split \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"extraction_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"split_config_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"async": false
}
'import requests
url = "https://api.runpulse.com/split"
payload = {
"extraction_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"split_config_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"async": False
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
extraction_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
split_config_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
async: false
})
};
fetch('https://api.runpulse.com/split', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.runpulse.com/split",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'extraction_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'split_config_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'async' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.runpulse.com/split"
payload := strings.NewReader("{\n \"extraction_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"split_config_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"async\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.runpulse.com/split")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"extraction_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"split_config_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"async\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.runpulse.com/split")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"extraction_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"split_config_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"async\": false\n}"
response = http.request(request)
puts response.read_body{
"split_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"split_output": {
"splits": {}
},
"credits_used": 123,
"plan_info": {
"tier": "<string>",
"total_credits_used": 123,
"pages_used": 1,
"note": "<string>"
}
}{
"job_id": "<string>",
"status": "pending",
"message": "<string>",
"queuedAt": "2023-11-07T05:31:56Z",
"credits_used": 123
}Overview
split_id to apply per-topic schemas./split endpoint analyzes a saved extraction and uses AI to map pages to your defined topics. This is useful for:
- Processing multi-section documents (e.g., annual reports, contracts)
- Applying different schemas to different parts of a document
- Organizing large documents by content type
/extract with storage enabled, which is the default).Async Mode
Setasync: true to return immediately with a job ID for polling. See Polling for Results for details.
{
"extraction_id": "abc123-def456",
"split_config": { "split_input": [...] },
"async": true
}
Request
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
extraction_id | uuid | Yes | ID of the saved extraction to split |
split_config | object | XOR | Inline split configuration with topics |
split_config_id | uuid | XOR | Reference to a saved split configuration |
async | boolean | No | If true, returns immediately with a job_id for polling. Default: false. |
Inline Config (split_config)
| Field | Type | Required | Description |
|---|---|---|---|
split_config.split_input | array | Yes | List of topics to identify. Also accepts legacy name topics for backward compatibility. |
split_input array:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Unique identifier for the topic |
description | string | No | Description of what content belongs to this topic |
Response
Synchronous Response (200)
| Field | Type | Description |
|---|---|---|
split_id | uuid | Unique identifier for this split result |
split_output | object | Contains splits — a mapping of topic names to arrays of 1-indexed page numbers |
Async Response (202)
| Field | Type | Description |
|---|---|---|
job_id | string | Job ID for polling |
status | string | "pending" |
message | string | Human-readable description |
Example Usage
Split with Inline Config
from pulse import Pulse
client = Pulse(api_key="YOUR_API_KEY")
split_result = client.split(
extraction_id="abc123-def456-ghi789",
split_config={
"split_input": [
{
"name": "financial_statements",
"description": "Balance sheets, income statements, cash flow statements"
},
{
"name": "executive_summary",
"description": "Letter to shareholders, company overview, highlights"
},
{
"name": "risk_factors",
"description": "Risk disclosures, forward-looking statements"
}
]
}
)
print(f"Split ID: {split_result.split_id}")
for topic, pages in split_result.split_output.splits.items():
print(f" {topic}: pages {pages}")
import { PulseClient } from "pulse-ts-sdk";
const client = new PulseClient({ apiKey: "YOUR_API_KEY" });
const splitResult = await client.split({
extraction_id: "abc123-def456-ghi789",
split_config: {
split_input: [
{ name: "financial_statements", description: "Balance sheets, income statements" },
{ name: "executive_summary", description: "Letter to shareholders" },
{ name: "risk_factors", description: "Risk disclosures" },
],
},
});
console.log("Split ID:", splitResult.split_id);
curl -X POST https://api.runpulse.com/split \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"extraction_id": "abc123-def456-ghi789",
"split_config": {
"split_input": [
{"name": "financial_statements", "description": "Balance sheets, income statements"},
{"name": "executive_summary", "description": "Letter to shareholders"},
{"name": "risk_factors", "description": "Risk disclosures"}
]
}
}'
Split with Saved Config Reference
split_result = client.split(
extraction_id="abc123-def456-ghi789",
split_config_id="config-uuid-456"
)
curl -X POST https://api.runpulse.com/split \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"extraction_id": "abc123-def456-ghi789", "split_config_id": "config-uuid-456"}'
Example Response
{
"split_id": "split-uuid-123",
"split_output": {
"splits": {
"financial_statements": [15, 16, 17, 18, 19, 20],
"executive_summary": [1, 2, 3, 4],
"risk_factors": [25, 26, 27, 28, 29, 30]
}
}
}
Using Split Results
After splitting, use thesplit_id with the /schema endpoint (split mode) to apply per-topic schemas:
split_id = split_result.split_id
schema_result = client.schema(
split_id=split_id,
split_schema_config={
"financial_statements": {
"schema": {"type": "object", "properties": {"revenue": {"type": "number"}}},
"schema_prompt": "Extract financial data"
},
"risk_factors": {
"schema": {"type": "object", "properties": {"risk_description": {"type": "string"}}}
}
}
)
Error Responses
| Status | Error | Description |
|---|---|---|
| 400 | Invalid request | Missing required fields or invalid topic format |
| 401 | Unauthorized | Invalid or missing API key |
| 404 | Extraction not found | The extraction_id doesn’t exist or you don’t have access |
| 429 | Rate limit exceeded | Too many requests |
| 500 | Processing error | Split processing failed |
Best Practices
Use descriptive topic names
Use descriptive topic names
/schema (split mode). Use clear, descriptive names like financial_statements rather than section_1.Provide detailed descriptions
Provide detailed descriptions
Use async for large documents
Use async for large documents
async: true to avoid request timeouts. See Polling for Results.Authorizations
Body
Request body for splitting a document into topics.
Provide EITHER split_config (inline) OR split_config_id (reference).
ID of the saved extraction to split.
Inline split configuration with topics. Required if split_config_id is not provided.
Show child attributes
Show child attributes
Reference to a saved split configuration. Use this instead of providing split_config inline.
If true, returns immediately with a job_id for polling via GET /job/{jobId}. Otherwise processes synchronously.
Response
Split result with page assignments (when async=false or omitted)
Result of document splitting with page assignments.
Unique identifier for this split result. Use this ID with the /schema endpoint (split mode) to apply schemas to specific page groups.
Page assignments per topic.
Show child attributes
Show child attributes
Number of credits consumed by this request. Only present when the organization has the credit billing system enabled.
Billing tier and cumulative usage information for the calling org, including this split run.
Show child attributes
Show child attributes