What's in the package
Every generated SDK is a complete, ready-to-publish package. This page covers what's in one, and how the code behaves when a developer uses it.
What's in the package
This is a generated TypeScript package. The other languages follow the same plan, with their own layout and tools.
README.md
CHANGELOG.md
LICENSE
package.json
sdk-manifest.json
src/
Acme.ts
client.ts
errors.ts
models.ts
methods/
users.ts
invoices.ts
types/
scripts/
mock
test
test/
| Path | What it holds |
|---|---|
README.md | Install, quickstart, authentication, behavior, errors and pagination. See README and samples |
CHANGELOG.md | The package's release history |
LICENSE | The package's license |
sdk-manifest.json | A language-neutral index of the public API: operations, request and response types, and models |
src/ | The client, one module per resource, and the models |
scripts/ and test/ | A local mock server and the test suite |
Typed models
Each schema in your spec becomes a named type. Models are split by API area, and you can put one in a specific folder with x-octri-sdk-tags.
Import models from the package's public exports. Internal file names can change between releases.
Validation before the request
The client checks arguments against your spec's constraints before sending anything. A bad argument raises SdkValidationError straight away, with no network call.
Errors
Every failure uses the same small set of types.
| Error | Meaning |
|---|---|
SdkValidationError | An argument failed a constraint in your spec, before any request |
SdkHttpError | The server returned a non-2xx response |
SdkApiError | A 2xx response whose error envelope reports a failure, for APIs that declare one |
SdkResponseDecodeError | A response didn't match its declared type. The raw body is kept |
SdkNetworkError | DNS, connection, TLS or socket failure |
SdkTimeoutError | An attempt ran past its timeout |
By status
Most languages raise a subclass of SdkHttpError, so a handler can catch only what it handles. Go has sentinel errors to check with errors.Is.
| Status | Most languages | Go |
|---|---|---|
| 400 | SdkBadRequestError | ErrBadRequest |
| 401 | SdkUnauthorizedError | ErrUnauthorized |
| 403 | SdkPermissionDeniedError | ErrPermissionDenied |
| 404 | SdkNotFoundError | ErrNotFound |
| 409 | SdkConflictError | ErrConflict |
| 422 | SdkUnprocessableEntityError | ErrUnprocessableEntity |
| 429 | SdkRateLimitError | ErrRateLimit |
| Any 5xx | SdkInternalServerError | ErrInternalServer |
Your error models
Declare the shape of your errors in your spec, and the SDK decodes the body for the caller:
try {
await client.users.create({ email: "not-an-email" });
} catch (error) {
if (error instanceof SdkHttpError) {
console.error(error.statusCode, error.data, error.requestId);
}
}error.data holds the decoded model. It's empty if the status declares no model or the body doesn't fit one, and the raw body stays on the error either way.
Response metadata
Methods return the typed body directly. Underneath, each request produces an envelope with the status, headers, request ID, latency and attempt count. In TypeScript, a developer can read it with a callback when creating the client:
const client = new Acme({
auth: { bearer: process.env.API_TOKEN! },
onResponse: (response) => {
console.log(response.statusCode, response.requestId, response.latencyMs);
},
});Middleware
In TypeScript, a developer can wrap every HTTP attempt. Middleware sees each retry, which makes it the place for tracing or extra headers.
const client = new Acme({
auth: { bearer: process.env.API_TOKEN! },
middleware: [
async (request, next) => {
const started = Date.now();
const response = await next(request);
console.log(request.method, Date.now() - started);
return response;
},
],
});For logic that you ship to everyone, rather than one developer's setup, use hooks.
Tests and a mock server
With Generated unit tests on, the package includes tests derived from your schema, a mock server, and a contract suite.
./scripts/mock --port 4010
./scripts/testscripts/mock starts a local server that answers from your schema, with no dependencies, so developers can work without calling your API. scripts/test runs the contract suite and then the native tests. The contract checks use the response examples you wrote in your spec, so good examples make for stronger tests.
Reporting to monitoring
If you've enabled monitoring, the SDK can report errors and traces. It stays off until the developer turns it on, and the README's Error telemetry line says what that package does.
Generated code
Don't edit generated files by hand: they're replaced on every build. To change behavior, use a setting, a hook or a spec transform.
From the CLI
octri lab files lists what a build generated, and octri lab cat prints one file.