Endpoint
Endpoint protocol schemas
API Mapping Schema Transform input/output data.
Source: packages/spec/src/api/endpoint.zod.ts
TypeScript Usage
import { ApiEndpointSchema, ApiMappingSchema } from '@objectstack/spec/api';
import type { ApiEndpoint, ApiMapping } from '@objectstack/spec/api';
// Validate data
const result = ApiEndpointSchema.parse(data);ApiEndpoint
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | ✅ | Unique endpoint ID |
| path | string | ✅ | URL Path — must be inside this stack's endpoint carve-out: /api/v1/apps/<manifest.namespace>/<subpath> with a non-empty subpath (ADR-0121 D1), e.g. /api/v1/apps/crm/leads for a stack whose manifest.namespace is crm. Only the subpath is yours to name; the namespace segment is derived from manifest.namespace (ADR-0121 D2), never authored here. A path outside the carve-out is rejected at publish and would match NOTHING at runtime. |
| method | Enum<'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS'> | ✅ | HTTP Method |
| summary | string | optional | |
| description | string | optional | |
| type | Enum<'flow' | 'script' | 'object_operation' | 'proxy'> | ✅ | Implementation type — only 'object_operation' and 'flow' EXECUTE in 17.x. 'script' and 'proxy' stay in the frozen vocabulary (#5040) and are rejected at publish, not parsed and ignored: express script logic as a flow whose script node runs your registered function, and an outbound call as a flow using a declared connector |
| target | string | ✅ | Target Flow ID or Script Name or Proxy URL, per type — but only the Flow ID is reachable in 17.x, since publish rejects type: 'script' and type: 'proxy' (an object_operation endpoint is addressed by objectParams.object / .operation; neither the publish gate nor the executor reads target for that type) |
| objectParams | { object?: string; operation?: Enum<'find' | 'get' | 'create' | 'update' | 'delete'> } | optional | For object_operation type |
| inputMapping | { source: string; target: string; transform?: string }[] | optional | Map Request Body to Internal Params |
| outputMapping | { source: string; target: string; transform?: string }[] | optional | Map Internal Result to Response Body |
| authRequired | boolean | ✅ | Require authentication |
| rateLimit | { enabled: boolean; windowMs: integer; maxRequests: integer } | optional | Rate limiting policy |
| cacheTtl | number | optional | Response cache TTL in seconds |
| _lock | Enum<'none' | 'no-overlay' | 'no-delete' | 'full'> | optional | Item-level lock — controls overlay & delete (ADR-0010). |
| _lockReason | string | optional | Human-readable reason shown when a write is refused by _lock. |
| _lockSource | Enum<'artifact' | 'package' | 'env-forced'> | optional | Layer that set _lock (artifact | package | env-forced). |
| _provenance | Enum<'package' | 'org' | 'env-forced'> | optional | Origin of the item (package | org | env-forced). |
| _packageId | string | optional | Owning package machine id. |
| _packageVersion | string | optional | Owning package version. |
| _lockDocsUrl | string | optional | Optional documentation link surfaced next to _lockReason. |
ApiMapping
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| source | string | ✅ | Source field/path |
| target | string | ✅ | Target field/path |
| transform | string | optional | Transformation function name — NOT EXECUTED in 17.x, and publish REJECTS the key: there is no transformation-function registry anywhere in the platform, so it stays in the frozen vocabulary and is refused rather than parsed and ignored (#5040 E7). A mapping entry moves and renames fields by dot path and nothing more — shape the value where it is produced instead (a flow endpoint whose flow computes it, or a formula field on the object) |