> For the complete documentation index, see [llms.txt](/llms.txt).
> A full single-fetch corpus is available at [llms-full.txt](/llms-full.txt).
---
title: Build a serverless endpoint in Go
description: Expose a typed Go workflow through AGNT5 signed HTTP dispatch without a persistent worker process.
last_verified: 2026-07-24
---

The Go serverless package implements the AGNT5 manifest, signed invocation, durable checkpoint, and suspension contract as an `http.Handler`. You can deploy it anywhere that provides a stable HTTPS endpoint.

<Callout type="info">
The Go adapter is beta. It supports typed workflows and functions, tools, agents with checkpointed session history, large payload references, durable steps, signals, user input, events, and budget or timer suspension.
</Callout>

## 1. Register a workflow

```go
package main

import (
    "context"
    "log"
    "net/http"
    "os"

    "github.com/agnt5dev/sdk-go/serverless"
)

type helloInput struct { Name string `json:"name"` }

func main() {
    handler := serverless.New(serverless.Options{
        ServiceName: "orders-api",
        ServiceVersion: os.Getenv("GIT_SHA"),
        SigningSecret: func(*http.Request) string {
            return os.Getenv("AGNT5_SERVERLESS_SIGNING_SECRET")
        },
    })

    _ = serverless.RegisterWorkflow(handler, "hello", func(
        ctx *serverless.Context,
        input helloInput,
    ) (map[string]string, error) {
        name, err := serverless.Step(ctx, "normalize-name", func(context.Context) (string, error) {
            if input.Name == "" { return "world", nil }
            return input.Name, nil
        })
        return map[string]string{"message": "hello " + name}, err
    })

    log.Fatal(http.ListenAndServe(":8787", handler))
}
```

Keep every `serverless.Step` name stable across releases. AGNT5 replays its checkpoint instead of executing the step again after reinvocation.

## 2. Register other components

Register typed functions, tools, and agents on the same handler:

```go
_ = serverless.RegisterFunction(handler, "normalize", normalizeOrder)

_ = serverless.RegisterTool(handler, serverless.Tool{
    Name: "order-status",
    Handler: func(ctx context.Context, input map[string]any) (any, error) {
        return lookupOrder(ctx, input["order_id"])
    },
})

_ = serverless.RegisterAgent(handler, serverless.Agent{
    Name: "support",
    Run: runSupportAgent,
})
```

Agent session messages are stored in the invoke checkpoint. Reinvocation restores that history before calling the agent runner.

## 3. Suspend and resume

Wait for an AGNT5 signal or user response without keeping the HTTP request open:

```go
approval, err := serverless.WaitForSignal[Approval](ctx, "approved", "approval-gate")
if err != nil { return Result{}, err }

answer, err := ctx.WaitForUser(serverless.UserInput{
    Question: "Release the order?",
    Type: "approval",
})
```

The first call returns a durable suspension. AGNT5 reinvokes the pinned deployment with the signal or user response in resume metadata.

## 4. Validate locally

```bash
export AGNT5_SERVERLESS_SIGNING_SECRET="$(openssl rand -base64 32)"
go run .
agnt5 serverless validate http://127.0.0.1:8787
```

Run validation from a second terminal.

## 5. Deploy and sync

Deploy the binary to an HTTPS host and configure the same signing secret. Then import the immutable release:

```bash
agnt5 serverless sync https://<go-host> \
  --provider node \
  --immutable-ref <git-sha-or-release-id> \
  --signing-secret-env AGNT5_SERVERLESS_SIGNING_SECRET \
  --activate=false
```

Run **`agnt5 serverless status --deployment-id <deployment-id> --verify`** before activation.

## Next steps

- [Serverless SDK reference](/docs/run/serverless-sdk-reference.md): compare language features and durable context methods.
- [Serverless protocol reference](/docs/run/serverless-protocol.md): inspect the signed request and response schemas.
- [Operate serverless endpoints](/docs/run/operate-serverless-endpoints.md): promote and recover releases safely.
