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/goGo 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/goSave 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
| Service | Methods |
|---|---|
Generate | Run, DownloadPackage |
Projects | List, Create, Get, Update, Delete, Generate |
Specs | Get, Update, Refresh |
SpecRevisions | List, Get, ListFiles |
Targets | List, Create, Get, Update, Delete, Adopt |
Drafts | List, Get, Update, ListFiles, Resolve, Recover |
Releases | List, Get, Republish |
Deliveries | List, Get |
Publications | List, Get |
Generations | List, Get, ListFiles, Wait |
Files | Get |
Organization | Get |
APIKeys | List, 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, ¬Found):
// no such project in this Organization
}See Errors for the envelope and codes.