Cookbook
Submit an advice record
POST a piece of advice into the Principal review queue, with model provenance, vulnerability flags, and metadata.
The shape of the request
ts
type VulnerabilityFlag = 'health' | 'life_event' | 'capability' | 'resilience';
type SubmitInput = {
// Required
documentUrl: string; // URL Bedrock can fetch the source document from
documentType: string; // e.g. "SUITABILITY_REPORT"
clientReference: string; // your stable client identifier
documentReference: string; // your stable document identifier
factFindSummary: Record<string, unknown>; // structured summary of the client fact find
// Optional
priority?: 'STANDARD' | 'URGENT';
modelProvider?: string; // e.g. "openai" — feeds the model registry
modelVersion?: string; // e.g. "gpt-4o-2024-08-06"
modelConfiguration?: Record<string, unknown>; // inference parameters (temperature, top_p, etc.)
// FG21/1 vulnerability routing — any non-empty array forces
// requiresSeniorSignOff: true and restricts the job to specialist
// reviewers. See /docs/features/vulnerability-routing.
vulnerabilityFlags?: VulnerabilityFlag[];
requiresSeniorSignOff?: boolean;
// Anonymised categorical segments for bias / fairness monitoring.
// Values are plain strings and aggregated across jobs on the
// /v1/firm/me/bias report — pick categorical labels rather than
// identifiers. See /docs/features/bias-monitoring.
clientSegments?: Record<string, string>;
};A complete TypeScript example
ts
import { request } from 'undici';
export async function submitAdvice(input: SubmitInput) {
const res = await request('https://api.bedrockcompliance.co.uk/v1/principal/jobs', {
method: 'POST',
headers: {
'X-Bedrock-Key': process.env.BEDROCK_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify(input),
});
if (res.statusCode === 403) {
throw new Error('Plan insufficient for principal services.');
}
if (res.statusCode === 422) {
throw new Error('Document download failed — check that documentUrl is reachable from Bedrock.');
}
if (res.statusCode !== 201) {
throw new Error(`Bedrock submit failed: ${res.statusCode}`);
}
return (await res.body.json()) as {
id: string;
status: 'QUEUED' | 'ASSIGNED' | 'IN_REVIEW' | 'COMPLETED';
};
}Calling it
ts
const job = await submitAdvice({
documentType: 'SUITABILITY_REPORT',
documentUrl: 'https://files.example.com/suitability-12345.pdf',
clientReference: 'client-12345',
documentReference: 'suitability-12345',
factFindSummary: {
adviser: 'Jane Smith',
product: 'Stocks & Shares ISA',
fundsValue: 25000,
},
priority: 'STANDARD',
modelProvider: 'openai',
modelVersion: 'gpt-4o-2024-08-06',
modelConfiguration: { temperature: 0.2, topP: 0.95 },
vulnerabilityFlags: ['health', 'life_event'], // routed to a specialist
clientSegments: {
ageBand: '65+',
riskProfile: 'Cautious',
productType: 'SIPP',
},
});
console.log('Submitted as', job.id);Common gotchas
- The documentUrl must be reachable from Bedrock. Presigned S3 URLs work well; URLs behind a VPN do not. A failed fetch returns
422. - Pin
modelVersionto an exact version, not a moving alias. Drift detection only works against pinned versions. - Set
clientReferenceanddocumentReferenceto stable values. They are how you join Bedrock data back to your customer and document records later.