Requests and responses
Build requests that remain safe under retries, version changes, partial failure, and App-specific authorization.
Request lifecycle
A protected Vision request crosses several independent checks:
- Resolve the approved HTTPS origin for the target resource server.
- Obtain a short-lived token for that server's exact audience, App entitlement, workspace, and minimum scope set.
- Encode the request exactly as the operation declares.
- Apply a client-generated correlation identifier where the operation accepts one.
- Bound connection and total response time.
- Check the HTTP status before parsing the success model.
- Parse the response against the matching App contract version.
- Retain the safe request or correlation identifier for support evidence.
- Retry only when the response and operation policy permit it.
Authentication is necessary but not sufficient. The resource server still enforces workspace, record visibility, state, role, and business rules.
Origins and versions
Vision Core currently declares:
https://vision.ivisionstudios.com
CRM, Calendar, and Accounting intentionally do not declare direct public origins in their approved contracts. Their operation pages show the exact path and mark the origin unresolved rather than constructing one. Use only an origin supplied for your approved environment.
Path families such as /platform/v1 and /api/crm/v1 are route-contract versions. Payloads may also carry a schemaVersion, and the OpenAPI document has its own semantic version. Treat all three as compatibility inputs.
Headers
- Name
Authorization- Type
- request
- Description
Protected operations require
Bearer <access-token>. Never send a token to a different audience or origin.
- Name
Accept- Type
- request
- Description
Use
application/jsonwhen the operation declares JSON responses.
- Name
Content-Type- Type
- request
- Description
Match the declared request representation. Token exchange is
application/x-www-form-urlencoded; most resource commands useapplication/json.
- Name
x-request-id- Type
- request and response
- Description
Vision Core accepts a safe
req_identifier or creates one. Other Apps may use a UUID correlation ID instead. Follow the operation's error schema; do not assume one identifier shape across every App.
- Name
vision-api-version- Type
- response
- Description
Vision Core identifies the served route family where implemented. Do not use this header as a substitute for parsing the documented payload schema.
- Name
Cache-Control- Type
- response
- Description
Authenticated private responses use
no-storewhere implemented. Clients must still avoid persisting tokens and private payloads in shared caches, browser storage, analytics, or logs.
Idempotency and conditional-write headers are operation-specific. Never add a plausible header and assume the server honors it; consult the operation page and idempotency and concurrency.
Bodies and encoding
- Send valid UTF-8.
- JSON property names and casing are contract-sensitive.
- A required field must be present even when another field appears to imply it.
null, omission, and an empty string are distinct unless the schema says otherwise.- Respect
const,enum, format, length, numeric, array, and pattern constraints shown on each operation page. - Treat
writeOnlyvalues as secrets and never expect them in a response. - Do not send fields marked
readOnly. - Unknown request-field behavior is not uniform. Closed schemas reject additional properties; otherwise consult the App contract.
- Timestamps use RFC 3339 date-time values with an explicit offset.
- Do not encode money as binary floating point unless an Accounting contract explicitly authorizes that representation.
Response handling
- Branch on status before deserializing a success model.
- Read the declared error envelope for the target App; error vocabularies are not yet identical.
- Preserve the request or correlation ID, status, operation, and safe timestamp.
- Ignore unknown optional response fields within a compatible version.
- Do not infer that
404proves a record does not exist; Apps may use non-disclosure. - A
2xxcommand receipt may prove durable acceptance without proving every downstream effect is complete. Read the operation's response semantics. - Treat malformed success or error bodies as integration failures and retain only non-sensitive diagnostic metadata.
Timeouts and cancellation
No estate-wide numeric timeout is currently part of the public contract. Set explicit connection and total response deadlines appropriate to your workload; never rely on library defaults that can wait indefinitely. A client-side timeout means the outcome is unknown, not necessarily failed. Before replaying a mutation, use its idempotency or receipt mechanism.
Cancelling the client request does not guarantee cancellation of server work. If an operation creates a durable command receipt, reconcile that receipt before trying again.
Example
Bounded server-side request
const controller = new AbortController()
const timeout = setTimeout(() => controller.abort(), 30_000)
try {
const response = await fetch(
'https://vision.ivisionstudios.com/platform/v1/apps',
{
headers: {
authorization: 'Bearer ' + process.env.VISION_ACCESS_TOKEN,
accept: 'application/json',
'x-request-id': `req_${crypto.randomUUID().replaceAll('-', '')}`,
},
signal: controller.signal,
cache: 'no-store',
},
)
const requestId = response.headers.get('x-request-id')
const body = await response.json()
if (!response.ok) {
throw new Error(
`Vision API ${response.status}; request ${requestId ?? 'unavailable'}`,
)
}
console.log(body)
} finally {
clearTimeout(timeout)
}
Use the generated operation page for the exact URL, scope, parameters, request schema, response schema, and error statuses.