Simple HTTP contract
Use one JSON request shape across languages and keep provider adapters behind the API boundary.
Use straightforward HTTP requests, typed response contracts and observable jobs to add AI enrichment without scattering provider-specific prompts across your codebase.

Strong defaults protect secrets, validate output and expose enough metadata to debug failures quickly.
Use one JSON request shape across languages and keep provider adapters behind the API boundary.
Generate application types from versioned schemas and surface nullable fields explicitly.
Develop against stable request and response examples before a production endpoint exists.
Retry safely with client-generated idempotency keys and bounded deadlines.
Return request identifiers, route metadata, stage timing and validation results.
Provide signature helpers and replay protection for asynchronous completion events.
These examples are interface documentation for the static launch site. Replace the endpoint only when a production backend is available.
type CompanyProfile = {
company_name: string;
industry: string | null;
summary: string;
location: {
city: string | null;
country: string | null;
};
semantic_tags: string[];
};
const response = await fetch("https://api.enrichapi.com/v1/enrich", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.ENRICH_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID()
},
body: JSON.stringify({
input: { company: "Example Robotics", website: "example.com" },
enrichments: ["company_summary", "industry", "location", "semantic_tags"],
schema: "company_profile_v1"
})
});
if (!response.ok) throw new Error(`Enrichment failed: ${response.status}`);
const result: { data: CompanyProfile } = await response.json();
import os
import uuid
import requests
response = requests.post(
"https://api.enrichapi.com/v1/enrich",
headers={
"Authorization": f"Bearer {os.environ['ENRICH_API_KEY']}",
"Content-Type": "application/json",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"input": {"company": "Example Robotics", "website": "example.com"},
"enrichments": ["company_summary", "industry", "location", "semantic_tags"],
"schema": "company_profile_v1",
},
timeout=15,
)
response.raise_for_status()
result = response.json()
curl --request POST \
--url https://api.enrichapi.com/v1/enrich \
--header "Authorization: Bearer $ENRICH_API_KEY" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: example-request-001" \
--data '{
"input": {"company": "Example Robotics", "website": "example.com"},
"enrichments": ["company_summary", "industry", "location", "semantic_tags"],
"schema": "company_profile_v1"
}'
A thin client and a separate domain service prevent network details from leaking across the application.
| Module | Responsibility | Test strategy |
|---|---|---|
enrich-client | HTTP, authentication, timeouts, retries and error parsing | Mock HTTP responses and retry classifications |
schemas | JSON Schema, generated types and version compatibility | Validate accepted and rejected fixture objects |
enrichment-service | Business rules, record selection and write-back decisions | Pure unit tests with fixture client |
jobs | Queue, idempotency, batch status and webhook processing | Integration tests with replayed events |
observability | Metrics, traces, request identifiers and redaction | Assertions that secrets and sensitive fields are absent |
A production enrichment pipeline needs regression tests that measure both structure and semantic quality.
Keep a representative set of easy, ambiguous and adversarial records. Review results by field because one aggregate score can hide a serious weakness.
Do not promote a prompt, model or routing change unless schema validity stays above the required threshold, critical-field accuracy does not regress and cost or latency remains within the task budget.
Static pages are public. Production requests belong on a protected server or worker, with data handling rules matched to your use case.
Use a secret manager or protected environment variables. Rotate and scope keys by environment.
Remove fields the enrichment task does not need and redact sensitive values from logs.
Limit each application key to approved schemas, record types or endpoint groups.
Verify webhook signatures, timestamps and delivery identifiers before processing.
Document retention, provider routing and regional requirements before sending customer data.
Maintain request tracing, revocation controls and a process for investigating unexpected access.
Use these answers as a checklist for the first implementation.
Start with one server-side endpoint, one schema and one fixture test. Add retries, webhooks and batch jobs only when the workflow requires them.