Docs · SDKs
Go SDK
Install the Go SDK, build a client, see every method with a Go sample, and verify records offline.
Install
Go
github.com/Invoance/invoance-go, a Go module.
Go 1.21 or later. Standard library only; every call takes a context and returns (value, error).
Terminal
go get github.com/Invoance/invoance-go
Client
| WithAPIKey | The API key. Falls back to INVOANCE_API_KEY; New returns a validation error when neither is set. |
|---|---|
| WithBaseURL | API host. Falls back to INVOANCE_BASE_URL, then https://api.invoance.com. Trailing slashes are removed. |
| WithAPIVersion | Path prefix put before every request path. Default v1. |
| WithTimeout | Per-request timeout. Default 30s; past it the error has KindTimeout. |
| WithHTTPClient | Your own *http.Client; its Timeout is used as is and WithTimeout is ignored. |
| WithIdempotencyKey | Default Idempotency-Key header for every mutating request; a per-call key wins. |
| WithExtraHeaders | Headers merged into every request. |
| Retries | None. Each request is sent once; on KindTimeout or KindNetwork, retry it yourself with the same Idempotency-Key. |
Go
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/Invoance/invoance-go"
)
func main() {
// Reads INVOANCE_API_KEY and INVOANCE_BASE_URL from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
// Or pass options.
configured, err := invoance.New(
invoance.WithAPIKey("invoance_live_..."),
invoance.WithBaseURL("https://api.invoance.com"),
invoance.WithTimeout(60*time.Second),
)
if err != nil {
log.Fatal(err)
}
_ = configured
// GET /v1/me checks no scope, so any live key passes. Never errors.
res := client.Validate(context.Background())
fmt.Println(res.Valid, res.Reason)
}
Methods
Every endpoint with a Go sample, by resource. Open a row for the sample; the link opens the endpoint card with its fields, response and errors.
EventsReference
POST/v1/events
Go
package main
import (
"context"
"fmt"
"log"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
// Reads INVOANCE_API_KEY from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
result, err := client.Events.Ingest(ctx, invoance.IngestEventParams{
EventType: "policy.approval",
EventTime: "2026-09-22T08:14:07Z",
Payload: map[string]any{
"policy_id": "pol_8472",
"approved_by": "risk_committee",
"decision": "approved",
},
IdempotencyKey: "policy-approval-pol_8472",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(result.EventID, result.IngestedAt)
}
GET/v1/events
Go
package main
import (
"context"
"fmt"
"log"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
// Reads INVOANCE_API_KEY from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
page, limit := 1, 50
list, err := client.Events.List(ctx, invoance.ListEventsParams{
Page: &page,
Limit: &limit,
EventType: "policy.approval",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(list.Total, list.HasMore)
for _, event := range list.Events {
fmt.Println(event.EventID, event.IngestedAt, event.PayloadHash)
}
}
GET/v1/events/{event_id}
Go
package main
import (
"context"
"fmt"
"log"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
// Reads INVOANCE_API_KEY from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
event, err := client.Events.Get(ctx, "7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4")
if err != nil {
log.Fatal(err)
}
fmt.Println(event.EventType, event.IngestedAt)
fmt.Println(event.PayloadHash, event.EventHash, event.RequestHash)
fmt.Println(event.Payload)
}
POST/v1/events/{event_id}/verify
Go
package main
import (
"context"
"fmt"
"log"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
// Reads INVOANCE_API_KEY from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
result, err := client.Events.Verify(ctx, "7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4", invoance.VerifyEventParams{
Payload: map[string]any{
"policy_id": "pol_8472",
"approved_by": "risk_committee",
"decision": "approved",
},
})
if err != nil {
log.Fatal(err)
}
matched := ""
if result.MatchedField != nil {
matched = *result.MatchedField
}
fmt.Println(result.MatchResult, matched)
fmt.Println(result.AnchoredHash, result.SubmittedHash, result.AnchoredAt)
}
DocumentsReference
POST/v1/document/anchor
Go
package main
import (
"context"
"crypto/sha256"
"encoding/hex"
"fmt"
"log"
"os"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
file, err := os.ReadFile("./INV-2026-0917.pdf")
if err != nil {
log.Fatal(err)
}
sum := sha256.Sum256(file)
documentHash := hex.EncodeToString(sum[:])
// Reads INVOANCE_API_KEY from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
result, err := client.Documents.Anchor(ctx, invoance.AnchorDocumentParams{
DocumentHash: documentHash,
DocumentRef: "INV-2026-0917.pdf",
EventType: "invoice.issued",
Metadata: map[string]any{
"invoice_number": "INV-2026-0917",
"amount": 5230,
"currency": "USD",
},
IdempotencyKey: "anchor-" + documentHash,
})
if err != nil {
log.Fatal(err)
}
fmt.Println(result.EventID, result.Status)
}
GET/v1/document
Go
package main
import (
"context"
"fmt"
"log"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
// Reads INVOANCE_API_KEY from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
limit := 25
page, err := client.Documents.List(ctx, invoance.ListDocumentsParams{
Limit: &limit,
DateFrom: "2026-09-01T00:00:00Z",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(page.Total, page.HasMore)
for _, d := range page.Documents {
fmt.Println(d.EventID, d.DocumentRef, d.HasOriginal)
}
}
GET/v1/document/{event_id}
Go
package main
import (
"context"
"fmt"
"log"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
// Reads INVOANCE_API_KEY from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
doc, err := client.Documents.Get(ctx, "7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4")
if err != nil {
log.Fatal(err)
}
fmt.Println(doc.DocumentHash, doc.HasOriginal, doc.CreatedAt)
if doc.Organization != nil {
fmt.Println(doc.Organization.IssuerName, doc.Organization.DomainVerified)
}
}
GET/v1/document/{event_id}/original
Go
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
// Reads INVOANCE_API_KEY from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
data, err := client.Documents.GetOriginal(ctx, "7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4")
if err != nil {
log.Fatal(err)
}
if err := os.WriteFile("./INV-2026-0917.pdf", data, 0o644); err != nil {
log.Fatal(err)
}
fmt.Println(len(data))
}
POST/v1/document/{event_id}/verify
Go
package main
import (
"context"
"crypto/sha256"
"encoding/hex"
"fmt"
"log"
"os"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
file, err := os.ReadFile("./INV-2026-0917.pdf")
if err != nil {
log.Fatal(err)
}
sum := sha256.Sum256(file)
// Reads INVOANCE_API_KEY from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
result, err := client.Documents.Verify(ctx, "7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4", invoance.VerifyDocumentParams{
DocumentHash: hex.EncodeToString(sum[:]),
})
if err != nil {
log.Fatal(err)
}
fmt.Println(result.MatchResult, result.AnchoredHash, result.AnchoredAt)
}
AI AttestationsReference
POST/v1/ai/attestations
Go
package main
import (
"context"
"fmt"
"log"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
// Reads INVOANCE_API_KEY from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
result, err := client.Attestations.Ingest(ctx, invoance.IngestAttestationParams{
Type: "output",
Input: "Summarize the termination clause in contract CT-8472.",
Output: "Either party may terminate with 30 days written notice. Early termination fees do not apply after month 12.",
ModelProvider: "openai",
ModelName: "gpt-4.1",
ModelVersion: "2026-04-14",
Subject: &invoance.AttestationSubject{
UserID: "u_4821",
SessionID: "sess_9f3a",
Extra: map[string]any{"department": "legal"},
},
IdempotencyKey: "ct-8472-summary-1",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(result.AttestationID, result.PayloadHash)
}
GET/v1/ai/attestations
Go
package main
import (
"context"
"fmt"
"log"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
// Reads INVOANCE_API_KEY from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
limit := 50
page, err := client.Attestations.List(ctx, invoance.ListAttestationsParams{
Limit: &limit,
AttestationType: "output",
ModelProvider: "openai",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(page.Total, page.HasMore, len(page.Attestations))
}
GET/v1/ai/attestations/{attestation_id}
Go
package main
import (
"context"
"fmt"
"log"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
// Reads INVOANCE_API_KEY from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
att, err := client.Attestations.Get(ctx, "7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4")
if err != nil {
log.Fatal(err)
}
fmt.Println(att.AttestationHash, att.SignatureAlg, att.PublicKey)
}
GET/v1/ai/attestations/{attestation_id}/raw
Go
package main
import (
"context"
"fmt"
"log"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
// Reads INVOANCE_API_KEY from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
raw, err := client.Attestations.GetRaw(ctx, "7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4")
if err != nil {
log.Fatal(err)
}
fmt.Println(raw["type"], raw["context"])
}
POST/v1/ai/attestations/{attestation_id}/verify
Go
package main
import (
"context"
"fmt"
"log"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
// Reads INVOANCE_API_KEY from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
result, err := client.Attestations.Verify(ctx, "7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4", invoance.VerifyAttestationParams{
ContentHash: "c4efe15781214a84046ad7e0592977c634a5cf45f4c1e06160daf760a295a8df",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(result.MatchResult)
if result.MatchedField != nil {
fmt.Println(*result.MatchedField)
}
}
TracesReference
POST/v1/traces
Go
package main
import (
"context"
"fmt"
"log"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
// Reads INVOANCE_API_KEY from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
trace, err := client.Traces.Create(ctx, invoance.CreateTraceParams{
Label: "Invoice batch 2026-09",
Metadata: map[string]any{"batch_id": "b_4471", "region": "eu-west"},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(trace.TraceID, trace.Status)
}
POST/v1/traces/{trace_id}/seal
Go
package main
import (
"context"
"fmt"
"log"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
// Reads INVOANCE_API_KEY from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
sealed, err := client.Traces.Seal(ctx, "7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4")
if err != nil {
log.Fatal(err)
}
fmt.Println(sealed.Status, sealed.Message)
}
Audit LogsReference
POST/v1/audit/events
Go
package main
import (
"context"
"fmt"
"log"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
// Reads INVOANCE_API_KEY from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
result, err := client.Audit.Events.Ingest(ctx, invoance.IngestAuditEventParams{
OrganizationID: "org_8472",
Action: "user.signed_in",
OccurredAt: "2026-09-22T08:14:07Z",
Actor: map[string]any{"type": "user", "id": "u_4821", "name": "Ada Lovelace"},
Targets: []map[string]any{{"type": "workspace", "id": "ws_17"}},
Context: map[string]any{"location": "203.0.113.10", "user_agent": "Mozilla/5.0"},
Metadata: map[string]any{"method": "sso", "mfa": true},
IdempotencyKey: "signin-u_4821-2026-09-22T08:14:07Z",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(result["event_id"], result["ingested_at"])
}
POST/v1/audit/orgs
Go
package main
import (
"context"
"fmt"
"log"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
// Reads INVOANCE_API_KEY from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
org, err := client.Audit.Orgs.Create(ctx, invoance.CreateAuditOrgParams{
OrganizationID: "org_8472",
Name: "Acme Robotics",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(org["id"], org["retention_days"])
}
PlatformReference
GET/v1/me
Go
package main
import (
"context"
"fmt"
"log"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
// Reads INVOANCE_API_KEY from the environment.
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
me, err := client.Me(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Println(me["organization"])
fmt.Println(me["limits"])
}
Verify offlineHow verification works
Two checks run without trusting the server: Attestations.VerifySignature fetches the record and checks its Ed25519 signature over signed_payload; VerifyAuditEventStruct (typed) and VerifyAuditEvent (map) rebuild the invoance.audit/1 bytes of an audit event and check its signature. Set PublicKey to pin the key from GET /keys/{domain} instead of the key on the row.
Go
package main
import (
"context"
"fmt"
"log"
"github.com/Invoance/invoance-go"
)
func main() {
ctx := context.Background()
client, err := invoance.New()
if err != nil {
log.Fatal(err)
}
// AI attestation: Ed25519 over signed_payload, checked locally.
sig, err := client.Attestations.VerifySignature(ctx, "a1d4f8c2-7b3e-4e9a-b5c6-0d2e8f4a7c19")
if err != nil {
log.Fatal(err)
}
fmt.Println(sig.Valid, sig.Reason)
// Audit event: canonical bytes rebuilt locally, signature checked
// against a pinned key (the public_key from GET /keys/{domain}, base64url decoded to hex).
pinnedHexKey := "d4443bd9d30ef4c2e0e5db03467e3c5c740358482c1a1e30cdb27a2e02a38176"
event, err := client.Audit.Events.Get(ctx, "aevt_01J8F3KQ2R7VWX9YB4ND6MCZAH")
if err != nil {
log.Fatal(err)
}
result := invoance.VerifyAuditEventStruct(event, &invoance.AuditVerifyOptions{PublicKey: pinnedHexKey})
fmt.Println(result.Valid, result.Reason, result.KeySource) // KeySource: "pinned"
}