CLI, MCP & SDKsSDKs

Go

Generate a context-first Go client for your API using only the standard library.

Typeship generates a context-first Go client for your API using only the standard library. This page covers Go-specific behavior; shared client behavior is on the SDK overview.

CLI and MCP packages are generated and released separately.

Module

  • The module path comes from the project's Go destination repository: github.com/acme/acme-go. Turn on Override module path at the bottom of the Go SDK settings only when the public import address must differ. Until a repository is set, the module path is a placeholder that go get cannot resolve.
  • The package name is read off the module path the way the Go ecosystem reads it. github.com/stripe/stripe-go is package stripe. A major-version suffix is ignored.
  • go.mod has no require block. The runtime is net/http and the standard library.
  • Every file passes gofmt -l. Every generation is gated on go build, go vet, and gofmt.

Idioms

  • Context first. Every method takes a context.Context. Cancel it to abort a request, a paginated iteration, or a stream.
  • (T, error) returns. Methods with no response body return error alone.
  • Params by pointer. Query and header parameters, and the fields of an inline object body, live in one XxxParams struct passed by pointer. nil means no parameters. Optional fields are pointers so absent and zero stay distinct; acme.Ptr(v) makes one inline.
  • Named bodies are arguments. A request body that is a $ref to a named schema, an array, or plain text is a positional body argument with its own type (AccountParams, []AccountParams, string), so a required body is enforced by the compiler.
  • Functional options. acme.New(acme.WithBearerToken(...), acme.WithTimeout(...)) for the client, acme.WithRequestTimeout(...) and friends per call.
  • Iterators. it := client.Accounts.List(ctx, nil), then for it.Next() { it.Value() } and it.Err().
  • Initialisms. Identifiers follow Go's convention: ID, AccountID, URL, HTTPStatus.

Environment variables

New reads these before options apply, so options always win:

VariableSets
ACME_TOKENbearer token
ACME_API_KEYthe API key, when the spec declares one
ACME_USERNAME / ACME_PASSWORDbasic auth
ACME_BASE_URLbase URL
ACME_WEBHOOK_KEYwebhook key

The prefix comes from your package name.

Errors

APIError carries Status, Body []byte, RequestID, and Message, plus a Decode(v any) error helper for the body. Per-status types such as *NotFoundError embed APIError, so errors.As matches at either precision. An undocumented status returns a bare *APIError. No response at all returns *TransportError with Method, URL, and a wrapped Err. A cancelled context returns ctx.Err().

Webhooks

client.Webhooks.Unwrap(payload, header) verifies and returns a *WebhookEvent carrying Type and the raw Data. Go has no sum types, so each declared event gets an accessor: event.AsAccountUpdated() returns the typed payload or an error if the type does not match. Events your module has not seen yet still arrive intact. VerifyWebhook and SignWebhook are exported for handlers that do not hold a client.

Streaming

client.Events.Stream(ctx) returns a *Stream. Read it like bufio.Scanner: Next, Event (an SSEEvent), Err, and Close. The stream uses a copy of the HTTP client with no timeout, so cancel through the context.

Uploads

A multipart/form-data field is an acme.Upload{Name, ContentType, Reader} on the params struct: the name and content type the server sees, and an io.Reader for the bytes. The other fields travel alongside as form parts. A raw binary body (application/octet-stream, image/png, ...) is a positional body io.Reader, sent under the spec's content type.

Unions

Go has no sum types. A oneOf/anyOf becomes a named union type that holds the JSON as received and decodes on request: As<Variant>() (Variant, error) and From<Variant>(v) per variant, Raw() for the bytes, and Discriminator() when the spec names one. It is the same shape oapi-codegen generates, and the same accessor pattern the webhook events use. A struct that pretended to be a union would silently drop fields; any would drop the typing.

Response metadata

WithAPIResponse(&meta) on any call fills an APIResponse{StatusCode, Header, RequestID, Body} from the last HTTP response (rate-limit headers, a Location, a request id to quote, or raw bytes for a future field or variant) without going through the global WithOnResponse hook. Go string-backed enum types already preserve unknown server values; generated constants provide autocomplete without closing the wire type.

GraphQL

A GraphQL schema generates one method per query and mutation field on client.Query and client.Mutation. Arguments are the params struct and become variables. Every scalar field to depth 2 is selected by default, with a fragment per concrete type for unions and interfaces, and WithSelection("{ id name }") overrides that per call on methods that return an object. Connection fields return an *Iter[T] like everything else. Errors in a 200 return *GraphQLError (which unwraps to *APIError) carrying the raw Errors.

On this page