Skip to main content

Altstack Together API Documentation

This page documents the contracts between Altstack families. For individual function signatures and every exported property, follow the linked family API pages.

Contract artifact map

Owning sourceDocument/artifactConsumerRuntime guarantee
server RouterOpenAPI from generateOpenAPISpecZod, Pydantic, or Rust generatorroute method, path, input schemas, success schemas, and declared error schemas
generated TypeScript OpenAPI moduleRequest mapApiClient through Fetch or Kyendpoint/method selection and request validation
generated TypeScript OpenAPI moduleResponse mapApiClient through Fetch or Kystatus-specific response parsing and result narrowing
Kafka routerAsyncAPI from generateAsyncAPISpec@alt-stack/zod-asyncapitopic names and message payload schemas
worker routerAsyncAPI from generateAsyncAPISpec@alt-stack/zod-asyncapijob names and payload schemas
generated AsyncAPI moduleTopics mapKafka or worker clientproducer-side payload validation and key-safe topic/job names

The document is a snapshot. Regenerate it after changing the owning router, then regenerate every consumer artifact.

HTTP Request map

The TypeScript OpenAPI generator emits a nested constant keyed by literal path and uppercase HTTP method:

const Request = {
"/api/users/{id}": {
GET: {
params: UserParamsSchema,
},
},
} as const;

A method with no params, query, headers, or body is still emitted as an empty object so EndpointsWithMethod can expose it to the typed client.

Client request options derive from the selected entry:

PropertyWhen available/required
paramsrequired for a declared params schema or braces in the endpoint path
queryavailable when the request entry has a query schema
bodythe current post, put, and patch method signatures always require this property; with a generated body schema its type is the inferred body, but without one its type becomes never, so a bodyless POST/PUT/PATCH cannot be called without an unsafe cast (a current type-level limitation)
headersalways optional caller headers; generated header schemas are represented in the request map but core request validation centers on params/query/body
timeoutoptional milliseconds for the executor
retriesoptional retry count, default 0
shouldRetryoptional callback receiving attempt, error, or response context

See HTTP client core API Documentation for the exact conditional types.

HTTP Response map

The generated Response map is keyed by path, method, and status string. ApiClient uses the actual numeric response status converted to a string to select a schema.

The returned union has three shapes:

BranchDiscriminants and payload
2xx responsesuccess: true, string code, body, raw; the body is schema-validated and typed for a declared status, but remains unvalidated/unknown for an undeclared 2xx status
declared non-2xx responsesuccess: false, string code, typed error, raw transport response
unexpected failuresuccess: false, numeric code, error: unknown, optional raw; used for undeclared non-2xx statuses and response-validation failures

If a status is missing from Response[path][method], an unlisted 2xx response is returned as success with an unvalidated body, while an unlisted non-2xx response becomes the numeric unexpected-failure branch.

Current server-error compatibility boundary

Server procedures declare a schema such as { _tag, userId }. OpenAPI contains that declared schema, but current adapters serialize a runtime envelope:

{
"error": {
"code": "UserNotFoundError",
"message": "User u_missing was not found",
"_tag": "UserNotFoundError",
"userId": "u_missing"
}
}

Generated clients validate against the OpenAPI schema, so a declared error response may fail validation unless the published contract accounts for the envelope. This is a documented current limitation, not a shape to silently normalize in client code.

AsyncAPI Topics map

@alt-stack/zod-asyncapi emits a constant whose keys are topic or job names and whose values are Zod payload schemas:

const Topics = {
"send-welcome": SendWelcomeMessageSchema,
} as const;

Kafka clients call send(topic, message, options?); worker clients call trigger(jobName, payload, options?) or triggerBatch. Both validate against the selected generated schema before invoking the transport.

The shared key map does not encode broker addresses, consumer groups, retry policy, topic provisioning, or worker routing strategy. Those remain runtime configuration.

Runtime ownership and shutdown

ComponentConstructionResource ownerShutdown
Hono servercreateServer returns a Hono apphost listener such as @hono/node-serverstop the host listener
Express servercreateServer returns an Express appNode HTTP server returned by listenclose the Node server
Bun servercreateServer calls Bun.servereturned Bun serverserver.stop()
TanStack Startroute adapter returns request handlersTanStack Start runtimehost lifecycle
Kafka/worker producer clientasync factory connects a producerreturned clientdisconnect()
WarpStream workerasync factory connects consumer resourcesreturned workerdisconnect()
Trigger.dev worker/clientTrigger.dev SDKTrigger.dev runtime/clientfollow Trigger.dev lifecycle

Compatibility checklist

Before releasing a coordinated contract change, verify:

  • package peer ranges match the selected framework, Zod, KafkaJS, or Trigger.dev versions;
  • the owner can regenerate OpenAPI or AsyncAPI without starting a listener or broker connection;
  • TypeScript generated output type-checks with Zod 4;
  • Python output imports under Python 3.11+ and Pydantic 2.7+;
  • Rust output compiles with the Rust 2021 toolchain and selected runtime dependency;
  • every documented status, error, topic, and job is exercised at the appropriate boundary;
  • long-lived clients and workers disconnect cleanly;
  • generated artifacts and the owning document change together in review.

Family API indexes