Typeship SDKs

Go

Generate packages and manage Typeship Projects from Go.

github.com/typeship-ax/go is the Go SDK for the Typeship API. Use it to generate packages, manage Projects, and inspect results from your application.

The module uses only net/http, with context-first methods, (T, error) returns, typed errors, pagination iterators, and gofmt-clean source.

Install

go get github.com/typeship-ax/go

Go 1.21 or newer. go.mod has no require block.

Create a client

The module path ends in go, but the package it declares is typeship, which is the identifier the import binds and the one you type:

import "github.com/typeship-ax/go"

client, err := typeship.New(typeship.WithBearerToken(os.Getenv("TYPESHIP_TOKEN")))
if err != nil {
	return err
}

Create a key in the Console under API keys. Pass it directly or set TYPESHIP_TOKEN.

New accepts base URL, timeout, retry, HTTP client, hook, debugging, and validation options. See Go for the option functions.

Generate a package

Generate.Run returns one generated package without creating a Project. Anonymous and Free requests generate 25 operations; paid plans generate the whole spec.

In a new directory, initialize a module and install the Typeship SDK:

go mod init example.com/generate-package
go get github.com/typeship-ax/go

Save this as main.go. It uses the hosted Petstore sample and needs no API key. Set TYPESHIP_TOKEN to use your organization's plan.

package main

import (
	"context"
	"fmt"
	"os"
	"path/filepath"

	"github.com/typeship-ax/go"
)

func main() {
	if err := run(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

func run() error {
	client, err := typeship.New()
	if err != nil {
		return err
	}
	var spec typeship.SpecInput
	if err := spec.FromURLSpecInput(typeship.URLSpecInput{
		URL: "https://typeship.dev/examples/petstore/openapi.yaml",
	}); err != nil {
		return err
	}

	result, err := client.Generate.Run(context.Background(), typeship.GenerateRequest{
		Spec: spec,
		Target:     typeship.GenerateRequestTarget{Generator: typeship.GeneratorKindGoSDK},
	}, nil)
	if err != nil {
		return err
	}
	for _, file := range result.Files {
		path := filepath.Join("out", file.Path)
		if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
			return fmt.Errorf("create directory for %s: %w", path, err)
		}
		if err := os.WriteFile(path, []byte(file.Content), 0o644); err != nil {
			return fmt.Errorf("write %s: %w", path, err)
		}
	}
	fmt.Println(len(result.Files), "files written to out/")
	return nil
}

The third argument to Generate.Run is *typeship.GenerateRunParams; pass nil when you do not need an idempotency key. Run the example from a directory where out/ can be created or replaced:

go run .
cd out
go test ./...

The program creates nested directories and overwrites matching files in out/. Generation or file-write errors stop it with a nonzero exit status.

Work with projects

var source typeship.SpecSourceInput
if err := source.FromURLSpecSourceInput(typeship.URLSpecSourceInput{
	Kind: "url",
	URL:  "https://api.parcel.example/openapi.json",
}); err != nil {
	return err
}

project, err := client.Projects.Create(ctx, typeship.CreateProjectRequest{
	Name: "Parcel API",
	Spec: typeship.SpecFields{Source: source},
	Targets: []typeship.InitialTargetFields{
		{Name: "Parcel Go SDK", Generator: typeship.GeneratorKindGoSDK},
		{Name: "Parcel CLI", Generator: typeship.GeneratorKindCLI},
		{Name: "Parcel MCP", Generator: typeship.GeneratorKindMCP},
	},
	AutoGenerate: typeship.Ptr(true),
}, nil)
if err != nil {
	return err
}

// Start regeneration, then wait for each Target's generated files.
generations, err := client.Projects.Generate(ctx, project.ID)
if err != nil {
	return err
}
for _, generation := range generations.Data {
	completed, err := client.Generations.Wait(ctx, string(generation.ID))
	if err != nil { return err }
	fmt.Println(completed.TargetID, completed.Status, completed.Errors)
}

// Walk history: the iterator fetches every page.
it := client.Generations.List(ctx, &typeship.GenerationsListParams{ProjectID: &project.ID})
for it.Next() {
	generation := it.Value()
	fmt.Println(generation.CreatedAt, generation.Trigger, generation.Status)
}
if err := it.Err(); err != nil {
	return err
}

Every method

ServiceMethods
GenerateRun, DownloadPackage
ProjectsList, Create, Get, Update, Delete, Generate
SpecsGet, Update, Refresh
SpecRevisionsList, Get, ListFiles
TargetsList, Create, Get, Update, Delete, Adopt
DraftsList, Get, Update, ListFiles, Resolve, Recover
ReleasesList, Get, Republish
DeliveriesList, Get
PublicationsList, Get
GenerationsList, Get, ListFiles, Wait
FilesGet
OrganizationGet
APIKeysList, Get, Revoke

Every method takes variadic RequestOption values last. Struct fields carry the API's snake_case names in their JSON tags.

api.md is the readable package reference. api.json provides the operations, schemas, examples, authentication, and agent safety metadata as structured data. The API reference has every schema.

Errors

Every method returns (T, error). Each status family (400, 401, 403, 404, 409, 422, 429, and 5xx) has one type, returned whether or not the operation documents the status, and all of them unwrap to *APIError:

_, err := client.Projects.Generate(ctx, "prj_...")

var payment *typeship.PaymentRequiredError
var notFound *typeship.NotFoundError
switch {
case errors.As(err, &payment):
	// free plan allowance used up; payment.Message says so
case errors.As(err, &notFound):
	// no such project in this Organization
}

See Errors for the envelope and codes.

On this page