Wire the current `/api/validate*` routes into your app, batch runner, or operator tooling.
RtU Integration
Use the current Souma proxy routes when you want your product or internal tooling to submit RtU checks through the same application surface the dashboard uses.
Current integration shape
- Submit one or more URLs with a usage purpose
- Souma accepts the batch and returns a
validation_idper request - Read results back through polling or SSE
- Surface completed checks in the same review workflow your operators use in the dashboard
Current proxy routes
| Route | Method | Use |
|---|---|---|
/api/validate | POST | Submit one or more validations |
/api/validate/results | GET | Fetch paginated result history |
/api/validate/result/:id | GET | Poll a single validation |
/api/validate/stream | GET | Stream updates for one or more validation IDs |
Authentication
These routes require a Souma API key in the Authorization header:
Authorization: Bearer YOUR_API_KEYGenerate the key from Dashboard > Integration > API Keys or during the workspace setup flow.
Submit a batch
curl -X POST http://localhost:3000/api/validate \
-H "Authorization: Bearer sk_prod_xxx" \
-H "Content-Type: application/json" \
-d '{
"validations": [
{
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://example.com/article",
"purpose": "AI model training"
}
]
}'Response shape
{
"results": [
{
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"validation_id": "val_abc123",
"status": "COMPLETED",
"url": "https://example.com/article",
"usage_purpose": "AI model training",
"allowed_for_use": "PERMITTED",
"confidence_score": 0.92,
"llm_reasoning": "The site's Terms of Service explicitly permit...",
"conditions": ["Attribution required"],
"policy_source_urls": ["https://example.com/terms"],
"created_at": "2026-03-20T10:30:00Z",
"completed_at": "2026-03-20T10:30:02Z"
}
]
}Notice the naming difference:
- request uses
purpose - response returns the normalized field as
usage_purpose
Batch strategy for large URL lists
Do not send one enormous URL list and block the UI while it runs. The current checker uses:
- batch size: 8 URLs
- concurrency: 2 active requests
- timeout budget: 24-25 seconds per submission call
That is a good default for production too.
const VALIDATION_BATCH_SIZE = 8
const VALIDATION_BATCH_CONCURRENCY = 2Polling a single result
curl -X GET http://localhost:3000/api/validate/result/val_abc123 \
-H "Authorization: Bearer sk_prod_xxx"Listing recent results
curl -X GET "http://localhost:3000/api/validate/results?limit=50&offset=0&status=COMPLETED" \
-H "Authorization: Bearer sk_prod_xxx"Real-time streaming
For long-running validations, use Server-Sent Events to get results as they complete:
const ids = result.results.map((r) => r.validation_id)
const params = ids.map((id) => `validation_ids=${id}`).join('&')
const eventSource = new EventSource(
`/api/validate/stream?${params}`
)
eventSource.addEventListener('result', (event) => {
const updated = JSON.parse(event.data)
console.log(updated.url, updated.allowed_for_use)
})
eventSource.addEventListener('done', () => {
eventSource.close()
})Timeouts and 504s
The current proxy returns 504 when the upstream call exceeds its timeout budget. In practice that means:
- the batch was too large
- one or more URLs were slow to fetch
- the validation should continue asynchronously instead of blocking the request
Recommended handling:
- keep batches small
- retry only the failed batch, not the entire workload
- persist partial successes immediately
- switch to polling or SSE once the batch is accepted
Next steps
- Right-to-Use - Understand verdicts and status handling
- Dashboard Overview - See where operators review results
- API Reference - Current route and payload reference