---
id: sdks.go
title: Go SDK Quickstart
summary: Consume the Go source module and use context-aware Fieldloop batch and receipt operations.
kind: quickstart
product_area: developer_tools
status: stable
updated: 2026-10-31
canonical: /docs/sdks/go
---

# Go SDK Quickstart

## Prerequisites and installation

Use Go 1.25.1+ and a `teammately-go` source checkout. In an application without an existing workspace:

```sh
go work init . /path/to/teammately-go
```

For an existing workspace, use `go work use /path/to/teammately-go`. Keep machine-local workspace configuration out of published module dependencies. The SDK module is `github.com/teammately/teammately-go`.

## Submit and inspect a batch

Inject `TEAMMATELY_API_KEY` through the host secret mechanism and configure the three destination identifiers below. This complete program sends one fictional record:

### Example: Context-aware batch submission

```go
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "os"

    teammately "github.com/teammately/teammately-go"
    "github.com/teammately/teammately-go/fieldloop"
)

func main() {
    if err := capture(context.Background()); err != nil { log.Fatal(err) }
}

func capture(ctx context.Context) error {
    client, err := teammately.New(teammately.Config{
        APIKey: os.Getenv("TEAMMATELY_API_KEY"),
    })
    if err != nil { return err }
    scope := fieldloop.Scope{
        Organization: os.Getenv("TEAMMATELY_ORGANIZATION"),
        Project: os.Getenv("TEAMMATELY_PROJECT"),
        Source: os.Getenv("TEAMMATELY_FIELDLOOP_SOURCE"),
    }
    batch, err := fieldloop.PrepareBatch([]fieldloop.Log{{
        SourceEventID: "support-ticket-1042:reply",
        OccurredAt: "2026-10-31T09:30:00Z",
        Input: json.RawMessage(`{"question":"Has my bicycle shipped?"}`),
        Output: json.RawMessage(`{"reply":"Your bicycle is being packed."}`),
    }}, "support-ticket-1042:batch-1")
    if err != nil { return err }
    receipt, err := client.Fieldloop.SubmitPrepared(
        ctx, scope, batch, teammately.RetryPolicy{})
    if err != nil { return err }
    processed, err := client.Fieldloop.WaitReceipt(
        ctx, scope, receipt.BatchID, fieldloop.PollOptions{})
    if err != nil { return err }
    fmt.Println(processed.AcceptedCount, processed.DuplicateCount,
        processed.ConflictCount, processed.RejectedCount)
    return nil
}
```

Pass the application's context and optional deadline in real services. Teammately supplies destination IDs; your application owns event/batch keys. `json.RawMessage` preserves captured JSON numbers.

## Continuous ingestion and evaluations

Use `fieldloop.NewIngestor(ctx, client.Fieldloop, scope, options)` for continuous ingestion. `Add` acknowledges memory; `Close` drains. Retain source records until admission is known. [Delivery and Recovery](/docs/sdks/delivery-and-recovery) explains pending batches and processing receipts.

`client.Evaluations` provides scoped context, criteria, results, comparisons, external submissions and managed API operations through `evaluations.Scope`. It does not package source or run an evaluator. Use the [CLI](/docs/cli) for local-file workflows.

## Related reference pages

{% related-card-grid %}
- [Fieldloop API](/docs/public-api/fieldloop)
- [Delivery and recovery](/docs/sdks/delivery-and-recovery)
- [Fieldloop troubleshooting](/docs/troubleshooting/fieldloop)
{% /related-card-grid %}
