tango

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 15, 2026 License: MIT Imports: 16 Imported by: 0

README

Tango Go SDK

Go Reference

In development — v0.1.0. Not yet at sibling-SDK parity. The public API may shift before v1.0.0. Pin to a specific tag if you depend on this in production.

Official Go SDK for the Tango API — federal contracts, IDVs, entities, opportunities, grants, vehicles, and more, with dynamic response shaping so you fetch only the fields you need.

The sibling SDKs (tango-node and tango-python) are at v1.0.0. This Go SDK ships the full transport, error model, retry/rate-limit handling, webhook signing, and a curated subset of resource methods. More endpoints land each 0.x release; see CHANGELOG.md for what's shipped.

Features

  • Dynamic response shaping — request exactly the fields you need via 21 built-in shape presets or a custom comma-separated field selector.
  • Typed errors*AuthError, *NotFoundError, *ValidationError, *RateLimitError, *TimeoutError, *APIError, all composable via errors.As / errors.Is.
  • Smart retries — automatic backoff on 5xx / 408 / 429 / transport errors, honoring the server's Retry-After header.
  • Generic paginationPaginatedResponse[T] envelope + Iterator[T] that walks every page for you.
  • Webhook signing — drop-in HMAC-SHA256 verification, http.Handler middleware included.
  • Standard-library only — no transitive dependencies.

Installation

go get github.com/makegov/tango-go

Requires Go 1.23 or later (for Iterator[T].Seq()'s iter.Seq2).

Quick Start

Initialize the client
import "github.com/makegov/tango-go"

client := tango.NewClient(
    tango.WithAPIKey("your-api-key"),
)

Or, when TANGO_API_KEY is set in the environment:

client := tango.NewClient()
List agencies
page, err := client.ListAgencies(ctx, nil)
if err != nil {
    log.Fatal(err)
}
for _, agency := range page.Results {
    fmt.Println(agency["agency_id"], agency["name"])
}
Get a specific agency

GetAgency returns a typed *AgencyRecord — use the named fields, or agency.Extra for anything the server adds that isn't first-classed yet.

agency, err := client.GetAgency(ctx, "9700")
if err != nil {
    log.Fatal(err)
}
fmt.Println(*agency.Name) // "Department of Defense"
Search contracts with a minimal shape
page, err := client.ListContracts(ctx, &tango.ListContractsOptions{
    ListOptions:    tango.ListOptions{Limit: 25, Shape: tango.ShapeContractsMinimal},
    AwardingAgency: "9700",
    AwardDateGte:   "2024-01-01",
    Sort:           "award_date",
    Order:          "desc",
})
Walk every contract matching a filter
iter := client.IterateContracts(ctx, &tango.ListContractsOptions{
    AwardingAgency: "9700",
    FiscalYear:     "2025",
})
for iter.Next() {
    c := iter.Item()
    fmt.Println(c["piid"], c["total_contract_value"])
}
if err := iter.Err(); err != nil {
    log.Fatal(err)
}
Get a fully-shaped entity
entity, err := client.GetEntity(ctx, "ABC123DEF456", &tango.GetEntityOptions{
    Shape: tango.ShapeEntitiesComprehensive,
})

Authentication

With API key
client := tango.NewClient(tango.WithAPIKey("your-key"))
From environment variable (TANGO_API_KEY)
export TANGO_API_KEY=your-key
client := tango.NewClient()

You can also override the base URL via TANGO_BASE_URL or tango.WithBaseURL("https://staging.tango.makegov.com") — useful for staging environments.

Core Concepts

Dynamic Response Shaping

Every list and get endpoint accepts a shape parameter. The SDK ships 21 presets matching the Node/Python SDKs:

// Use a preset
page, _ := client.ListContracts(ctx, &tango.ListContractsOptions{
    ListOptions: tango.ListOptions{Shape: tango.ShapeContractsMinimal},
})

// Or roll your own
page, _ = client.ListContracts(ctx, &tango.ListContractsOptions{
    ListOptions: tango.ListOptions{Shape: "key,piid,recipient(uei,display_name)"},
})
Pagination

List endpoints support both page-based (Page) and cursor-based (Cursor) pagination. PaginatedResponse[T] carries both Next (the full URL) and Cursor (extracted from Next for keyset endpoints).

page, _ := client.ListIDVs(ctx, &tango.ListIDVsOptions{
    ListOptions: tango.ListOptions{Limit: 50},
})
// Fetch the next page:
nextPage, _ := client.ListIDVs(ctx, &tango.ListIDVsOptions{
    ListOptions: tango.ListOptions{Limit: 50, Cursor: page.Cursor},
})

Or just iterate:

iter := client.IterateIDVs(ctx, nil)
for iter.Next() {
    // iter.Item() is the next IDV
}
Rate limits

After each request, client.RateLimitInfo() returns a snapshot of the rate-limit headers:

info := client.RateLimitInfo()
fmt.Printf("%d/%d remaining; resets in %ds\n", info.Remaining, info.Limit, info.ResetIn)

The client also automatically retries 429s, honoring Retry-After.

Webhook verification
import "github.com/makegov/tango-go/webhooks"

http.Handle("/tango-webhook", webhooks.Middleware(os.Getenv("WEBHOOK_SECRET"),
    http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // signature already verified; r.Body is reset and ready to read
        var delivery map[string]any
        json.NewDecoder(r.Body).Decode(&delivery)
        // process delivery...
        w.WriteHeader(http.StatusNoContent)
    }),
))

For lower-level use:

ok := webhooks.Verify(rawBody, r.Header.Get(webhooks.SignatureHeader), secret)

Error Handling

Every error returned by the SDK can be unwrapped to one of the typed error types:

_, err := client.GetAgency(ctx, "bogus")
var nf *tango.NotFoundError
if errors.As(err, &nf) {
    // handle 404 specifically
}

var rle *tango.RateLimitError
if errors.As(err, &rle) {
    log.Printf("rate limited; retry after %ds (limit type: %s)", rle.RetryAfter, rle.LimitType)
}

// Catch-all
var apiErr *tango.APIError
if errors.As(err, &apiErr) {
    log.Printf("status=%d data=%v", apiErr.StatusCode, apiErr.ResponseData)
}

tango.IsRetryable(err) reports whether the SDK considers err retryable (it already retries internally — this helper is for callers building their own retry policies).

API Methods

The SDK exposes ~94 methods on *Client covering every endpoint in the sibling Node/Python SDKs. The most-used 15 are listed here; the full method-by-method reference lives in docs/API_REFERENCE.md.

Resource List Get Iterate
Agencies ListAgencies GetAgency (typed: *AgencyRecord)
Contracts ListContracts IterateContracts
Entities ListEntities GetEntity IterateEntities
IDVs ListIDVs GetIDV IterateIDVs
Vehicles ListVehicles GetVehicle IterateVehicles
OTAs ListOTAs GetOTA IterateOTAs
OTIDVs ListOTIDVs GetOTIDV IterateOTIDVs
Opportunities ListOpportunities IterateOpportunities
Notices ListNotices IterateNotices
Forecasts ListForecasts IterateForecasts
Grants ListGrants IterateGrants
Protests ListProtests GetProtest (typed: *ProtestRecord) IterateProtests
IT Dashboard ListItDashboard GetItDashboard IterateItDashboard
NAICS / PSC ListNAICS / ListPSC GetNAICS / GetPSC
Webhooks (CRUD) ListWebhookEndpoints / ListWebhookAlerts Get… / Create… / Update… / Delete…

Sub-resources and lookups are also covered: ListEntityContracts / IDVs / OTAs / OTIDVs / Subawards / Lcats, ListIDVAwards / ChildIDVs / Transactions / Lcats, ListAgencyAwardingContracts / FundingContracts, ListVehicleAwardees / Orders, ListOTIDVAwards, ListGsaElibraryContracts, ListBusinessTypes, ListOffices, ListDepartments (deprecated), ListMasSins, ListAssistanceListings, ListLcats, plus all three metrics getters (GetNAICSMetrics / GetPSCMetrics / GetEntityMetrics) and the dispatcher ListMetrics. Meta: Resolve, Validate, GetVersion, ListAPIKeys, SearchOpportunityAttachments. Webhook signing: webhooks.Generate / Verify / Parse / VerifyRequest / Middleware.

See docs/API_REFERENCE.md for full signatures, filter fields, and quirks per method.

Project Structure

.
├── client.go          # Client + NewClient + accessors
├── options.go         # Functional options
├── transport.go       # HTTP, auth, retries, rate-limit parsing
├── errors.go          # Typed error tree
├── pagination.go      # PaginatedResponse[T] + Iterator[T]
├── shapes.go          # Shape preset constants + DefaultBaseURL
├── internal.go        # ListOptions + generic helpers
├── version.go         # SDK version constant
├── contracts.go       # ListContracts + IterateContracts
├── entities.go        # ListEntities + GetEntity + IterateEntities
├── idvs.go            # ListIDVs + GetIDV + IterateIDVs
├── vehicles.go        # ListVehicles + GetVehicle
├── opportunities.go   # opportunities, notices, forecasts, grants
├── lookups.go         # agencies, organizations, NAICS, PSC, subawards, version
├── resolve.go         # Resolve + Validate
├── client_test.go     # Transport + resource tests
├── webhooks/
│   ├── signing.go     # Generate / Verify / Parse
│   ├── handler.go     # VerifyRequest + Middleware
│   └── signing_test.go
├── examples/          # Runnable example programs
├── CHANGELOG.md
├── LICENSE
└── README.md

Development

go test ./...            # run unit tests
go test -race ./...      # with the race detector
go vet ./...             # static checks

Requirements

  • Go 1.23 or later.

Documentation

In-repo guides under docs/:

  • docs/ARCHITECTURE.md — package layout, request lifecycle, design rationale
  • docs/CLIENT.mdNewClient options, env vars, retry semantics, error model, rate-limit observability, iterator surface
  • docs/API_REFERENCE.md — method-by-method reference for every public method (~94)
  • docs/SHAPES.md — shape grammar, the 21 Shape* presets, Flat / FlatLists, trade-offs
  • docs/WEBHOOKS.md — receiving deliveries, CRUD methods, troubleshooting

External:

License

MIT — see LICENSE.

Support

Open an issue at https://github.com/makegov/tango-go/issues or email support@makegov.com.

Contributing

PRs welcome. Run go test ./... and go vet ./... before opening. For larger work, open an issue first so we can align on the API shape — public methods on *Client are a stability surface from 1.0.0 onward.

Documentation

Overview

Package tango is the official Go SDK for the Tango API.

The Tango API provides programmatic access to federal-contracting data — contracts, IDVs, entities, opportunities, grants, vehicles, and more — with dynamic response shaping so callers fetch only the fields they need.

Quick start:

client := tango.NewClient(tango.WithAPIKey("…"))

page, err := client.ListContracts(ctx, &tango.ListContractsOptions{
    AwardingAgency: "9700",
    Shape:          tango.ShapeContractsMinimal,
    Limit:          25,
})

Documentation: https://docs.makegov.com

Index

Constants

View Source
const (
	MetricsOwnerNAICS  = "naics"
	MetricsOwnerPSC    = "psc"
	MetricsOwnerEntity = "entity"
)

MetricsOwnerType enumerates the three owner types under which Tango exposes rolling-window metrics.

View Source
const (
	// ShapeContractsMinimal — default for ListContracts.
	ShapeContractsMinimal = "key,piid,award_date,recipient(display_name),description,total_contract_value"

	// ShapeEntitiesMinimal — default for ListEntities.
	ShapeEntitiesMinimal = "uei,legal_business_name,cage_code,business_types"

	// ShapeEntitiesComprehensive — default for GetEntity.
	ShapeEntitiesComprehensive = "uei,legal_business_name,dba_name,cage_code," +
		"business_types,primary_naics,naics_codes,psc_codes," +
		"email_address,entity_url,description,capabilities,keywords," +
		"physical_address,mailing_address," +
		"federal_obligations(*),congressional_district"

	// ShapeForecastsMinimal — default for ListForecasts.
	ShapeForecastsMinimal = "id,title,anticipated_award_date,fiscal_year,naics_code,status"

	// ShapeOpportunitiesMinimal — default for ListOpportunities.
	ShapeOpportunitiesMinimal = "opportunity_id,title,solicitation_number,response_deadline,active"

	// ShapeNoticesMinimal — default for ListNotices.
	ShapeNoticesMinimal = "notice_id,title,solicitation_number,posted_date"

	// ShapeProtestsMinimal — default for ListProtests.
	ShapeProtestsMinimal = "case_id,case_number,title,source_system,outcome,filed_date"

	// ShapeGrantsMinimal — default for ListGrants.
	ShapeGrantsMinimal = "grant_id,opportunity_number,title,status(*),agency_code"

	// ShapeIDVsMinimal — default for ListIDVs.
	ShapeIDVsMinimal = "key,piid,award_date,recipient(display_name,uei),description,total_contract_value,obligated,idv_type"

	// ShapeIDVsComprehensive — default for GetIDV.
	ShapeIDVsComprehensive = "key,piid,award_date,description,fiscal_year,total_contract_value,obligated," +
		"idv_type,multiple_or_single_award_idv,type_of_idc,period_of_performance(start_date,last_date_to_order)," +
		"recipient(display_name,legal_business_name,uei,cage)," +
		"awarding_office(*),funding_office(*),place_of_performance(*),parent_award(key,piid)," +
		"competition(*),legislative_mandates(*),transactions(*),subawards_summary(*)"

	// ShapeVehiclesMinimal — default for ListVehicles.
	ShapeVehiclesMinimal = "uuid,solicitation_identifier,is_synthetic_solicitation,program_acronym," +
		"organization_id,organization,vehicle_type,description," +
		"idv_count,awardee_count,order_count,total_obligated," +
		"vehicle_obligations,vehicle_contracts_value,latest_award_date," +
		"solicitation_title,solicitation_date"

	// ShapeVehiclesComprehensive — default for GetVehicle.
	ShapeVehiclesComprehensive = "uuid,solicitation_identifier,is_synthetic_solicitation,agency_id,program_acronym," +
		"organization_id,organization(*),vehicle_type,who_can_use," +
		"solicitation_title,solicitation_description,solicitation_date,opportunity_id," +
		"naics_code,psc_code,set_aside," +
		"fiscal_year,award_date,latest_award_date,last_date_to_order," +
		"description,idv_count,awardee_count,order_count,total_obligated," +
		"vehicle_obligations,vehicle_contracts_value," +
		"type_of_idc,contract_type,metrics(*)"

	// ShapeVehicleAwardeesMinimal — default for ListVehicleAwardees.
	ShapeVehicleAwardeesMinimal = "uuid,key,piid,award_date,title,order_count,idv_obligations,idv_contracts_value,recipient(display_name,uei)"

	// ShapeVehicleOrdersMinimal — default for ListVehicleOrders.
	ShapeVehicleOrdersMinimal = "key,piid,award_date,obligated,total_contract_value,description,recipient(display_name,uei)"

	// ShapeOrganizationsMinimal — default for ListOrganizations.
	ShapeOrganizationsMinimal = "key,fh_key,name,level,type,short_name"

	// ShapeOTAsMinimal — default for ListOTAs.
	ShapeOTAsMinimal = "key,piid,award_date,recipient(display_name,uei),description,total_contract_value,obligated"

	// ShapeOTIDVsMinimal — default for ListOTIDVs.
	ShapeOTIDVsMinimal = "key,piid,award_date,recipient(display_name,uei),description,total_contract_value,obligated,idv_type"

	// ShapeSubawardsMinimal — default for ListSubawards. The API rejects "id"
	// and "amount" in subaward shapes; stick to the canonical fields.
	ShapeSubawardsMinimal = "award_key,prime_recipient(uei,display_name),subaward_recipient(uei,display_name)"

	// ShapeGsaElibraryContractsMinimal — default for ListGsaElibraryContracts.
	ShapeGsaElibraryContractsMinimal = "uuid,contract_number,schedule,recipient(display_name,uei),idv(key,award_date)"

	// ShapeItdashboardInvestmentsMinimal — default for ListItdashboardInvestments.
	// Matches the API's INVESTMENT_LIST_DEFAULT_SHAPE.
	ShapeItdashboardInvestmentsMinimal = "uii,agency_name,bureau_name,investment_title," +
		"type_of_investment,part_of_it_portfolio,updated_time,url"

	// ShapeItdashboardInvestmentsComprehensive — default for GetItdashboardInvestment.
	// Matches the API's INVESTMENT_RETRIEVE_DEFAULT_SHAPE.
	ShapeItdashboardInvestmentsComprehensive = "uii,agency_code,agency_name,bureau_code,bureau_name," +
		"investment_title,type_of_investment,part_of_it_portfolio," +
		"updated_time,url"
)

Shape presets mirror the canonical defaults in tango-node and tango-python. Pass any of these (or a custom comma-separated field list) via the Shape option on a list/get call to control which fields the API returns.

View Source
const DefaultBaseURL = "https://tango.makegov.com"

DefaultBaseURL is the public Tango SaaS endpoint.

View Source
const Version = "0.1.0"

Version is the tango-go SDK version. Keep in sync with CHANGELOG.md and the git tag at release time.

Variables

This section is empty.

Functions

func IsRetryable

func IsRetryable(err error) bool

IsRetryable reports whether the SDK should retry after this error. Used internally by the transport's retry loop; exposed because external callers occasionally want to drive their own retry policies.

Types

type APIError

type APIError struct {
	// StatusCode is the HTTP status code, or 0 for transport-level errors
	// (timeouts, DNS, connection refused).
	StatusCode int

	// Message is a human-readable description.
	Message string

	// ResponseData is the decoded JSON body of the error response, when
	// present. It is typed as any because the server returns a mix of
	// shapes (object, array, string, null).
	ResponseData any

	// Cause is the underlying error, if any (e.g. a *json.SyntaxError
	// from a malformed response body or a *net.OpError from a network
	// failure). Preserved so callers can errors.As/Is through it.
	Cause error
}

APIError is the base error type returned by the SDK for any HTTP-layer failure. Specific error types embed *APIError, so callers can use errors.As(err, &tango.AuthError{}) for the specific cases, or errors.As(err, &tango.APIError{}) for the catch-all.

func (*APIError) Error

func (e *APIError) Error() string

Error implements the error interface.

func (*APIError) Unwrap

func (e *APIError) Unwrap() error

Unwrap returns the underlying cause, if any, so errors.Is / errors.As can traverse to wrapped errors (e.g. *json.SyntaxError).

type AgencyContractsOptions

type AgencyContractsOptions struct {
	ListOptions

	// Joiner is the separator used when flat=true to join nested keys.
	// Default on the server side is ".". Only meaningful when Flat is set.
	Joiner string

	// Ordering is the server-side sort spec. Endpoint-specific allowlist;
	// prefix with "-" for descending.
	Ordering string

	// Search is a free-text search filter.
	Search string

	// Extra forwards arbitrary query params that don't have a typed field.
	Extra map[string]any
}

AgencyContractsOptions controls filtering and shaping for the agency contract sub-resource endpoints: /api/agencies/{code}/contracts/awarding/ and /api/agencies/{code}/contracts/funding/.

Mirrors the Node SDK AgencyContractsOptions interface.

type AgencyRecord

type AgencyRecord struct {
	AgencyID     *string        `json:"agency_id,omitempty"`
	Name         *string        `json:"name,omitempty"`
	Abbreviation *string        `json:"abbreviation,omitempty"`
	Code         *string        `json:"code,omitempty"`
	Department   map[string]any `json:"department,omitempty"`

	// Extra captures any forward-compatible fields the server adds that
	// aren't in the typed surface yet. Not serialized on the way out.
	Extra map[string]any `json:"-"`
}

AgencyRecord is the typed response from GetAgency. Mirrors `AgencyRecord` in `tango-node/src/types.ts`. All fields are pointers so the zero value distinguishes "absent" from "explicit empty/null".

func (*AgencyRecord) UnmarshalJSON

func (a *AgencyRecord) UnmarshalJSON(data []byte) error

UnmarshalJSON catches forward-compatible fields into Extra.

type AuthError

type AuthError struct{ *APIError }

AuthError is raised on HTTP 401.

func (*AuthError) Error

func (e *AuthError) Error() string

Error implements the error interface.

func (*AuthError) Unwrap

func (e *AuthError) Unwrap() error

Unwrap returns the embedded *APIError so errors.As / errors.Is can traverse to the base error type.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is the Tango API client. Construct one with NewClient and pass it around — Client is safe for concurrent use.

func NewClient

func NewClient(opts ...Option) *Client

NewClient constructs a Client. The API key is taken from the WithAPIKey option, falling back to the TANGO_API_KEY environment variable. The base URL is taken from WithBaseURL, falling back to TANGO_BASE_URL, then DefaultBaseURL.

Calling NewClient with no options is valid and useful in environments where TANGO_API_KEY is set (CI, container, dev shell).

func (*Client) BaseURL

func (c *Client) BaseURL() string

BaseURL returns the resolved base URL the client will hit.

func (*Client) CreateWebhookAlert

func (c *Client) CreateWebhookAlert(ctx context.Context, input WebhookAlertCreateInput) (*WebhookAlert, error)

CreateWebhookAlert creates a filter-based subscription. POST /api/webhooks/alerts/.

`Name`, `QueryType`, and a non-empty `Filters` map are required. `QueryType` is SINGULAR (e.g. `"contract"`, not `"contracts"`). For accounts with multiple webhook endpoints, set `Endpoint` to the destination endpoint UUID; single-endpoint accounts may omit it.

func (*Client) CreateWebhookEndpoint

func (c *Client) CreateWebhookEndpoint(ctx context.Context, input WebhookEndpointCreateInput) (*WebhookEndpoint, error)

CreateWebhookEndpoint creates a new webhook endpoint. POST /api/webhooks/endpoints/.

`Name` and `CallbackURL` are required. The Tango API enforces unique(user, name) on endpoints — raising client-side here gives a cleaner error than the server's 400 on duplicate. Matches the v1.0.0 behavior in `tango-node` and `tango-python` (see tango-node CHANGELOG, 1.0.0).

func (*Client) DeleteWebhookAlert

func (c *Client) DeleteWebhookAlert(ctx context.Context, id string) error

DeleteWebhookAlert removes an alert by id. DELETE /api/webhooks/alerts/{id}/.

func (*Client) DeleteWebhookEndpoint

func (c *Client) DeleteWebhookEndpoint(ctx context.Context, id string) error

DeleteWebhookEndpoint removes an endpoint by id. DELETE /api/webhooks/endpoints/{id}/.

func (*Client) GetAgency

func (c *Client) GetAgency(ctx context.Context, code string) (*AgencyRecord, error)

GetAgency fetches a single agency by code (e.g. "9700" for DoD).

Returns a typed *AgencyRecord (v1.0.0 — breaking change from v0.1.0, which returned Record). Use the named fields when present, or AgencyRecord.Extra for forward-compatible fields the server adds that aren't in the typed surface yet.

func (*Client) GetAssistanceListing

func (c *Client) GetAssistanceListing(ctx context.Context, number string) (Record, error)

GetAssistanceListing fetches a single Assistance Listing (CFDA program) by its CFDA number (e.g. "10.001").

func (*Client) GetBusinessType

func (c *Client) GetBusinessType(ctx context.Context, code string) (Record, error)

GetBusinessType fetches a single business-type reference record by its short code. Returns *NotFoundError when the code is unknown.

func (*Client) GetDepartment

func (c *Client) GetDepartment(ctx context.Context, code string) (Record, error)

GetDepartment fetches a single department by its code (typically the CGAC department code, e.g. "097" for DoD).

func (*Client) GetEntity

func (c *Client) GetEntity(ctx context.Context, key string, opts *GetEntityOptions) (Record, error)

GetEntity fetches a single entity by UEI or CAGE code.

When shape is empty, the API returns its comprehensive default. Pass ShapeEntitiesMinimal (or your own) for a slimmer payload.

func (*Client) GetEntityMetrics

func (c *Client) GetEntityMetrics(ctx context.Context, uei string, months int, periodGrouping string) (Record, error)

GetEntityMetrics returns rolling-window metrics for an entity (by UEI). Endpoint: GET /api/entities/{uei}/metrics/{months}/{periodGrouping}/. Mirrors Node `getEntityMetrics` and Python `get_entity_metrics`.

func (*Client) GetGsaElibraryContract

func (c *Client) GetGsaElibraryContract(ctx context.Context, uuid string, opts *GetEntityOptions) (Record, error)

GetGsaElibraryContract fetches a single GSA eLibrary contract by UUID.

Note: this is a Python-only method (the Node SDK has no equivalent single-record getter). Included here for parity with tango-python.

func (*Client) GetIDV

func (c *Client) GetIDV(ctx context.Context, key string, opts *GetEntityOptions) (Record, error)

GetIDV fetches a single IDV by key.

func (*Client) GetIDVSummary deprecated

func (c *Client) GetIDVSummary(ctx context.Context, identifier string) (Record, error)

GetIDVSummary fetches the summary roll-up for an IDV by its solicitation identifier (/api/idvs/{identifier}/summary/).

Deprecated: the v1.0.0 server returns 404 for this endpoint per the upstream Node SDK CHANGELOG. The method is retained for parity; callers should migrate to GetIDV with a richer shape.

func (*Client) GetItDashboard

func (c *Client) GetItDashboard(ctx context.Context, uii string, opts *GetEntityOptions) (Record, error)

GetItDashboard fetches a single IT Dashboard investment by UII (Unique Investment Identifier).

func (*Client) GetMasSin

func (c *Client) GetMasSin(ctx context.Context, sin string) (Record, error)

GetMasSin fetches a single MAS SIN by its identifier (e.g. "54151S").

func (*Client) GetNAICS

func (c *Client) GetNAICS(ctx context.Context, code string) (Record, error)

GetNAICS fetches a single NAICS by code.

func (*Client) GetNAICSMetrics

func (c *Client) GetNAICSMetrics(ctx context.Context, code string, months int, periodGrouping string) (Record, error)

GetNAICSMetrics returns rolling-window metrics for a NAICS code. Endpoint: GET /api/naics/{code}/metrics/{months}/{periodGrouping}/. Mirrors Node `getNAICSMetrics` and Python `get_naics_metrics`.

func (*Client) GetOTA

func (c *Client) GetOTA(ctx context.Context, key string, opts *GetEntityOptions) (Record, error)

GetOTA fetches a single OTA by key.

func (*Client) GetOTIDV

func (c *Client) GetOTIDV(ctx context.Context, key string, opts *GetEntityOptions) (Record, error)

GetOTIDV fetches a single OTIDV by key.

func (*Client) GetOffice

func (c *Client) GetOffice(ctx context.Context, code string) (Record, error)

GetOffice fetches a single office by its FPDS-NG office code.

func (*Client) GetOrganization

func (c *Client) GetOrganization(ctx context.Context, key string) (Record, error)

GetOrganization fetches a single organization by key.

func (*Client) GetPSC

func (c *Client) GetPSC(ctx context.Context, code string) (Record, error)

GetPSC fetches a single PSC by code.

func (*Client) GetPSCMetrics

func (c *Client) GetPSCMetrics(ctx context.Context, code string, months int, periodGrouping string) (Record, error)

GetPSCMetrics returns rolling-window metrics for a PSC code. Endpoint: GET /api/psc/{code}/metrics/{months}/{periodGrouping}/. Mirrors Node `getPSCMetrics` and Python `get_psc_metrics`.

func (*Client) GetProtest

func (c *Client) GetProtest(ctx context.Context, caseNumber string, opts *GetEntityOptions) (*ProtestRecord, error)

GetProtest fetches a single protest by case number / case ID.

Returns a typed *ProtestRecord (one of the few typed-struct return values in the SDK, mirroring the Node `ProtestRecord` interface). Use shape=...,dockets(...) to include nested docket entries.

func (*Client) GetVehicle

func (c *Client) GetVehicle(ctx context.Context, uuid string, opts *GetEntityOptions) (Record, error)

GetVehicle fetches a single vehicle by UUID.

func (*Client) GetVersion

func (c *Client) GetVersion(ctx context.Context) (Record, error)

GetVersion returns the API version metadata.

func (*Client) GetWebhookAlert

func (c *Client) GetWebhookAlert(ctx context.Context, id string) (*WebhookAlert, error)

GetWebhookAlert fetches a single alert by id. GET /api/webhooks/alerts/{id}/.

func (*Client) GetWebhookEndpoint

func (c *Client) GetWebhookEndpoint(ctx context.Context, id string) (*WebhookEndpoint, error)

GetWebhookEndpoint fetches a single endpoint by id. GET /api/webhooks/endpoints/{id}/.

func (*Client) GetWebhookSamplePayload

func (c *Client) GetWebhookSamplePayload(ctx context.Context, eventType string) (*WebhookSamplePayloadResponse, error)

GetWebhookSamplePayload fetches a sample webhook delivery body for the given event type. If `eventType` is empty, the server returns samples for all event types (the "all-types" variant of WebhookSamplePayloadResponse). GET /api/webhooks/endpoints/sample-payload/?event_type=<type>.

func (*Client) IterateContracts

func (c *Client) IterateContracts(ctx context.Context, opts *ListContractsOptions) *Iterator[Record]

IterateContracts returns an Iterator that walks every contract matching the given options. The iterator follows ?page= or ?cursor= on the server's next URL automatically.

Classic loop:

it := client.IterateContracts(ctx, &tango.ListContractsOptions{AwardingAgency: "9700"})
for it.Next() {
    fmt.Println(it.Item()["piid"])
}
if err := it.Err(); err != nil { return err }

Go 1.23+ range-over-func:

for c, err := range client.IterateContracts(ctx, opts).Seq() {
    if err != nil { return err }
    fmt.Println(c["piid"])
}

func (*Client) IterateEntities

func (c *Client) IterateEntities(ctx context.Context, opts *ListEntitiesOptions) *Iterator[Record]

IterateEntities walks every entity matching opts.

func (*Client) IterateForecasts

func (c *Client) IterateForecasts(ctx context.Context, opts *ListForecastsOptions) *Iterator[Record]

IterateForecasts walks every forecast matching opts.

func (*Client) IterateGrants

func (c *Client) IterateGrants(ctx context.Context, opts *ListGrantsOptions) *Iterator[Record]

IterateGrants walks every grant matching opts.

func (*Client) IterateGsaElibraryContracts

func (c *Client) IterateGsaElibraryContracts(ctx context.Context, opts *ListGsaElibraryContractsOptions) *Iterator[Record]

IterateGsaElibraryContracts walks every GSA eLibrary contract matching opts.

func (*Client) IterateIDVs

func (c *Client) IterateIDVs(ctx context.Context, opts *ListIDVsOptions) *Iterator[Record]

IterateIDVs walks every IDV matching opts.

func (*Client) IterateItDashboard

func (c *Client) IterateItDashboard(ctx context.Context, opts *ListItDashboardOptions) *Iterator[Record]

IterateItDashboard walks every IT Dashboard investment matching opts.

func (*Client) IterateLcats

func (c *Client) IterateLcats(ctx context.Context, opts *ListLcatsOptions) *Iterator[Record]

IterateLcats walks every LCAT for the owner specified by opts. One of opts.UEI or opts.IDVKey must be set.

func (*Client) IterateNotices

func (c *Client) IterateNotices(ctx context.Context, opts *ListNoticesOptions) *Iterator[Record]

IterateNotices walks every notice matching opts.

func (*Client) IterateOTAs

func (c *Client) IterateOTAs(ctx context.Context, opts *ListOTAsOptions) *Iterator[Record]

IterateOTAs walks every OTA matching opts.

func (*Client) IterateOTIDVAwards

func (c *Client) IterateOTIDVAwards(ctx context.Context, key string, opts *ListOTIDVAwardsOptions) *Iterator[Record]

IterateOTIDVAwards walks every child award under the given OTIDV.

func (*Client) IterateOTIDVs

func (c *Client) IterateOTIDVs(ctx context.Context, opts *ListOTIDVsOptions) *Iterator[Record]

IterateOTIDVs walks every OTIDV matching opts.

func (*Client) IterateOpportunities

func (c *Client) IterateOpportunities(ctx context.Context, opts *ListOpportunitiesOptions) *Iterator[Record]

IterateOpportunities walks every opportunity matching opts.

func (*Client) IterateProtests

func (c *Client) IterateProtests(ctx context.Context, opts *ListProtestsOptions) *Iterator[Record]

IterateProtests walks every protest matching opts.

func (*Client) IterateVehicles

func (c *Client) IterateVehicles(ctx context.Context, opts *ListVehiclesOptions) *Iterator[Record]

IterateVehicles walks every vehicle matching opts.

func (*Client) LastResponseHeaders

func (c *Client) LastResponseHeaders() http.Header

LastResponseHeaders returns the response headers from the most recent completed request (useful for X-Request-Id, X-Tango-Trace-Id, etc.). Returns nil if no request has completed.

func (*Client) ListAPIKeys

func (c *Client) ListAPIKeys(ctx context.Context) (Record, error)

ListAPIKeys returns the authenticated user's API keys. Endpoint: GET /api/api-keys/.

Unlike the other list endpoints, this one does not paginate — it returns a structured object with the caller's keys and metadata. Mirrors Node `listAPIKeys` and Python `list_api_keys`.

func (*Client) ListAgencies

func (c *Client) ListAgencies(ctx context.Context, opts *ListAgenciesOptions) (*PaginatedResponse[Record], error)

ListAgencies queries /api/agencies/.

func (*Client) ListAgencyAwardingContracts

func (c *Client) ListAgencyAwardingContracts(ctx context.Context, code string, opts *AgencyContractsOptions) (*PaginatedResponse[Record], error)

ListAgencyAwardingContracts lists contracts where the given agency is the awarding agency (/api/agencies/{code}/contracts/awarding/).

func (*Client) ListAgencyFundingContracts

func (c *Client) ListAgencyFundingContracts(ctx context.Context, code string, opts *AgencyContractsOptions) (*PaginatedResponse[Record], error)

ListAgencyFundingContracts lists contracts where the given agency is the funding agency (/api/agencies/{code}/contracts/funding/).

func (*Client) ListAssistanceListings

func (c *Client) ListAssistanceListings(ctx context.Context, opts *ListOptions) (*PaginatedResponse[Record], error)

ListAssistanceListings queries /api/assistance_listings/ — the CFDA (Catalog of Federal Domestic Assistance) program catalog. Mirrors Node `listAssistanceListings` and Python `list_assistance_listings`.

opts may be nil for defaults (server page size).

func (*Client) ListBusinessTypes

func (c *Client) ListBusinessTypes(ctx context.Context, opts *ListOptions) (*PaginatedResponse[Record], error)

ListBusinessTypes queries /api/business_types/ — the reference list of SBA / SAM.gov socioeconomic and structural designations (8(a), woman-owned, veteran-owned, non-profit, etc.). Mirrors the Node `listBusinessTypes` and Python `list_business_types` methods.

opts may be nil for defaults (server page size).

func (*Client) ListContracts

func (c *Client) ListContracts(ctx context.Context, opts *ListContractsOptions) (*PaginatedResponse[Record], error)

ListContracts queries /api/contracts/.

func (*Client) ListDepartments deprecated

func (c *Client) ListDepartments(ctx context.Context, opts *ListOptions) (*PaginatedResponse[Record], error)

ListDepartments queries /api/departments/ — the legacy standalone departments endpoint. Mirrors Node `listDepartments` (marked @deprecated in the Node SDK — see comment below) and Python `list_departments`.

Deprecated: prefer ListOrganizations with Level=1 for new code. The standalone /api/departments/ endpoint is retained for backward compatibility and will be removed in a future API version (tango#1461, legacy agency tables retirement).

func (*Client) ListEntities

func (c *Client) ListEntities(ctx context.Context, opts *ListEntitiesOptions) (*PaginatedResponse[Record], error)

ListEntities queries /api/entities/.

func (*Client) ListEntityContracts

func (c *Client) ListEntityContracts(ctx context.Context, uei string, opts *EntitySubresourceOptions) (*PaginatedResponse[Record], error)

ListEntityContracts lists contracts awarded to an entity (/api/entities/{uei}/contracts/).

func (*Client) ListEntityIDVs

func (c *Client) ListEntityIDVs(ctx context.Context, uei string, opts *EntitySubresourceOptions) (*PaginatedResponse[Record], error)

ListEntityIDVs lists IDVs held by an entity (/api/entities/{uei}/idvs/).

func (*Client) ListEntityLcats

func (c *Client) ListEntityLcats(ctx context.Context, uei string, opts *EntityLcatsOptions) (*PaginatedResponse[Record], error)

ListEntityLcats lists Labor Categories (LCATs) advertised by an entity (/api/entities/{uei}/lcats/).

func (*Client) ListEntityOTAs

func (c *Client) ListEntityOTAs(ctx context.Context, uei string, opts *EntitySubresourceOptions) (*PaginatedResponse[Record], error)

ListEntityOTAs lists Other Transaction Awards (OTAs) held by an entity (/api/entities/{uei}/otas/).

func (*Client) ListEntityOTIDVs

func (c *Client) ListEntityOTIDVs(ctx context.Context, uei string, opts *EntitySubresourceOptions) (*PaginatedResponse[Record], error)

ListEntityOTIDVs lists Other Transaction IDVs (OTIDVs) held by an entity (/api/entities/{uei}/otidvs/).

func (*Client) ListEntitySubawards

func (c *Client) ListEntitySubawards(ctx context.Context, uei string, opts *EntitySubawardsOptions) (*PaginatedResponse[Record], error)

ListEntitySubawards lists subawards reported against contracts held by the given entity (/api/entities/{uei}/subawards/).

func (*Client) ListForecasts

func (c *Client) ListForecasts(ctx context.Context, opts *ListForecastsOptions) (*PaginatedResponse[Record], error)

ListForecasts queries /api/forecasts/.

func (*Client) ListGrants

func (c *Client) ListGrants(ctx context.Context, opts *ListGrantsOptions) (*PaginatedResponse[Record], error)

ListGrants queries /api/grants/.

func (*Client) ListGsaElibraryContracts

func (c *Client) ListGsaElibraryContracts(ctx context.Context, opts *ListGsaElibraryContractsOptions) (*PaginatedResponse[Record], error)

ListGsaElibraryContracts queries /api/gsa_elibrary_contracts/ — GSA eLibrary contract listings.

func (*Client) ListIDVAwards

func (c *Client) ListIDVAwards(ctx context.Context, key string, opts *ListIDVsOptions) (*PaginatedResponse[Record], error)

ListIDVAwards lists task-order awards under a parent IDV (/api/idvs/{key}/awards/). Filtering mirrors ListIDVs; pagination is cursor-based on the server side.

func (*Client) ListIDVChildIDVs

func (c *Client) ListIDVChildIDVs(ctx context.Context, key string, opts *ListIDVsOptions) (*PaginatedResponse[Record], error)

ListIDVChildIDVs lists child IDVs nested under a parent IDV (/api/idvs/{key}/idvs/). Filtering mirrors ListIDVs.

func (*Client) ListIDVLcats

func (c *Client) ListIDVLcats(ctx context.Context, key string, opts *EntityLcatsOptions) (*PaginatedResponse[Record], error)

ListIDVLcats lists Labor Categories (LCATs) under an IDV (/api/idvs/{key}/lcats/). Re-uses EntityLcatsOptions because the server accepts the same parameter shape on both /entities/{uei}/lcats/ and /idvs/{key}/lcats/.

func (*Client) ListIDVSummaryAwards deprecated

func (c *Client) ListIDVSummaryAwards(ctx context.Context, identifier string, opts *ListOptions) (*PaginatedResponse[Record], error)

ListIDVSummaryAwards lists awards belonging to an IDV summary (/api/idvs/{identifier}/summary/awards/).

Deprecated: the v1.0.0 server returns 404 for this endpoint per the upstream Node SDK CHANGELOG. The method is retained for parity; callers should migrate to ListIDVAwards.

func (*Client) ListIDVTransactions

func (c *Client) ListIDVTransactions(ctx context.Context, key string, opts *ListOptions) (*PaginatedResponse[Record], error)

ListIDVTransactions lists the raw transaction history backing an IDV (/api/idvs/{key}/transactions/). The endpoint only accepts pagination params; pass a *ListOptions with Limit/Cursor (or Page).

func (*Client) ListIDVs

func (c *Client) ListIDVs(ctx context.Context, opts *ListIDVsOptions) (*PaginatedResponse[Record], error)

ListIDVs queries /api/idvs/.

func (*Client) ListItDashboard

func (c *Client) ListItDashboard(ctx context.Context, opts *ListItDashboardOptions) (*PaginatedResponse[Record], error)

ListItDashboard queries /api/itdashboard/ — federal IT investments.

func (*Client) ListLcats

func (c *Client) ListLcats(ctx context.Context, opts *ListLcatsOptions) (*PaginatedResponse[Record], error)

ListLcats lists Labor Categories (LCATs) owned by either an entity (when UEI is set) or an IDV (when IDVKey is set). One of the two must be set, or ListLcats returns *ValidationError.

LCATs do not exist at the top level — they're always scoped to a parent resource. Use this method as a convenience when you want a single entry point; if you already know which owner type you want, call ListEntityLcats or ListIDVLcats directly.

func (*Client) ListMasSins

func (c *Client) ListMasSins(ctx context.Context, opts *ListMasSinsOptions) (*PaginatedResponse[Record], error)

ListMasSins queries /api/mas_sins/ — the canonical list of GSA Multiple Award Schedule (MAS) Special Item Numbers. Mirrors Node `listMasSins` and Python `list_mas_sins`.

func (*Client) ListMetrics

func (c *Client) ListMetrics(ctx context.Context, opts ListMetricsOptions) (Record, error)

ListMetrics is a convenience dispatcher that routes to one of GetNAICSMetrics, GetPSCMetrics, or GetEntityMetrics based on opts.OwnerType. Mirrors Node `listMetrics`.

Returns *ValidationError on unknown OwnerType, empty OwnerID, non-positive Months, or empty PeriodGrouping.

func (*Client) ListNAICS

func (c *Client) ListNAICS(ctx context.Context, opts *ListNAICSOptions) (*PaginatedResponse[Record], error)

ListNAICS queries /api/naics/.

func (*Client) ListNotices

func (c *Client) ListNotices(ctx context.Context, opts *ListNoticesOptions) (*PaginatedResponse[Record], error)

ListNotices queries /api/notices/.

func (*Client) ListOTAs

func (c *Client) ListOTAs(ctx context.Context, opts *ListOTAsOptions) (*PaginatedResponse[Record], error)

ListOTAs queries /api/otas/ — OTA (Other Transaction Authority) award actions.

func (*Client) ListOTIDVAwards

func (c *Client) ListOTIDVAwards(ctx context.Context, key string, opts *ListOTIDVAwardsOptions) (*PaginatedResponse[Record], error)

ListOTIDVAwards queries /api/otidvs/{key}/awards/ — the child awards under a given OTIDV parent.

func (*Client) ListOTIDVs

func (c *Client) ListOTIDVs(ctx context.Context, opts *ListOTIDVsOptions) (*PaginatedResponse[Record], error)

ListOTIDVs queries /api/otidvs/ — OTIDV parent records.

func (*Client) ListOffices

func (c *Client) ListOffices(ctx context.Context, opts *ListOfficesOptions) (*PaginatedResponse[Record], error)

ListOffices queries /api/offices/ — the canonical list of federal contracting offices (FPDS-NG hierarchy). Mirrors Node `listOffices` and Python `list_offices`.

func (*Client) ListOpportunities

func (c *Client) ListOpportunities(ctx context.Context, opts *ListOpportunitiesOptions) (*PaginatedResponse[Record], error)

ListOpportunities queries /api/opportunities/.

func (*Client) ListOrganizations

func (c *Client) ListOrganizations(ctx context.Context, opts *ListOrganizationsOptions) (*PaginatedResponse[Record], error)

ListOrganizations queries /api/organizations/.

func (*Client) ListPSC

func (c *Client) ListPSC(ctx context.Context, opts *ListOptions) (*PaginatedResponse[Record], error)

ListPSC queries /api/psc/.

func (*Client) ListProtests

func (c *Client) ListProtests(ctx context.Context, opts *ListProtestsOptions) (*PaginatedResponse[Record], error)

ListProtests queries /api/protests/ — bid protests from GAO + COFC.

func (*Client) ListSubawards

func (c *Client) ListSubawards(ctx context.Context, opts *ListSubawardsOptions) (*PaginatedResponse[Record], error)

ListSubawards queries /api/subawards/.

func (*Client) ListVehicleAwardees

func (c *Client) ListVehicleAwardees(ctx context.Context, uuid string, opts *ListOptions) (*PaginatedResponse[Record], error)

ListVehicleAwardees lists the awardees (entities holding child IDVs) under a contracting vehicle (/api/vehicles/{uuid}/awardees/).

func (*Client) ListVehicleOrders

func (c *Client) ListVehicleOrders(ctx context.Context, uuid string, opts *ListOptions) (*PaginatedResponse[Record], error)

ListVehicleOrders lists task orders placed under a contracting vehicle's child IDVs (/api/vehicles/{uuid}/orders/).

This endpoint exists in the Python SDK (list_vehicle_orders) but not the Node SDK; it's included here for full parity.

func (*Client) ListVehicles

func (c *Client) ListVehicles(ctx context.Context, opts *ListVehiclesOptions) (*PaginatedResponse[Record], error)

ListVehicles queries /api/vehicles/.

func (*Client) ListWebhookAlerts

func (c *Client) ListWebhookAlerts(ctx context.Context, opts *ListOptions) (*PaginatedResponse[WebhookAlert], error)

ListWebhookAlerts returns the caller's filter-based subscriptions. GET /api/webhooks/alerts/.

func (*Client) ListWebhookEndpoints

func (c *Client) ListWebhookEndpoints(ctx context.Context, opts *ListOptions) (*PaginatedResponse[WebhookEndpoint], error)

ListWebhookEndpoints returns the caller's configured webhook endpoints. GET /api/webhooks/endpoints/.

func (*Client) ListWebhookEventTypes

func (c *Client) ListWebhookEventTypes(ctx context.Context) (*WebhookEventTypesResponse, error)

ListWebhookEventTypes returns the set of event types the server can emit. GET /api/webhooks/event-types/.

func (*Client) RateLimitInfo

func (c *Client) RateLimitInfo() *RateLimitInfo

RateLimitInfo returns a snapshot of the rate-limit headers from the most recent response. Returns nil if no request has completed yet.

func (*Client) Resolve

func (c *Client) Resolve(ctx context.Context, input ResolveInput) (*ResolveResult, error)

Resolve POSTs to /api/resolve/ to fuzzy-match a name to entity or organization candidates.

func (*Client) SearchOpportunityAttachments

func (c *Client) SearchOpportunityAttachments(ctx context.Context, opts SearchOpportunityAttachmentsOptions) (Record, error)

SearchOpportunityAttachments runs a semantic search over opportunity attachment extracted text. Endpoint: GET /api/opportunities/attachment-search/. Mirrors Node `searchOpportunityAttachments` and Python `search_opportunity_attachments`.

Returns *ValidationError if opts.Q is empty.

func (*Client) TestWebhookEndpoint

func (c *Client) TestWebhookEndpoint(ctx context.Context, endpointID string) (*WebhookTestDeliveryResult, error)

TestWebhookEndpoint triggers a test delivery for a specific endpoint. POST /api/webhooks/endpoints/test-delivery/ with body {"endpoint": "<id>"}.

The canonical request key is `endpoint` (as of tango#2252); the server still accepts the legacy `endpoint_id` alias for backward compatibility, but the SDK sends the canonical key.

func (*Client) UpdateWebhookAlert

func (c *Client) UpdateWebhookAlert(ctx context.Context, id string, input WebhookAlertUpdateInput) (*WebhookAlert, error)

UpdateWebhookAlert patches an existing alert. Only `Name`, `Frequency`, `CronExpression`, and `IsActive` are writable server-side. PATCH /api/webhooks/alerts/{id}/.

func (*Client) UpdateWebhookEndpoint

func (c *Client) UpdateWebhookEndpoint(ctx context.Context, id string, input WebhookEndpointUpdateInput) (*WebhookEndpoint, error)

UpdateWebhookEndpoint patches an existing endpoint. Only fields set on the input struct are sent (nil pointer == omit). PATCH /api/webhooks/endpoints/{id}/.

func (*Client) Validate

func (c *Client) Validate(ctx context.Context, input ValidateInput) (*ValidateResult, error)

Validate POSTs to /api/validate/ to check whether an identifier is well-formed and known.

type EntityLcatsOptions

type EntityLcatsOptions struct {
	ListOptions

	// Ordering is the server-side sort spec.
	Ordering string

	// Search is a free-text search filter.
	Search string

	// Extra forwards arbitrary query params that don't have a typed field.
	Extra map[string]any
}

EntityLcatsOptions filters /api/entities/{uei}/lcats/ and /api/idvs/{key}/lcats/. Minimal: pagination + shape + ordering + search.

type EntitySubawardsOptions

type EntitySubawardsOptions struct {
	ListOptions

	// Ordering must match the subawards endpoint's allowlist (e.g.
	// "last_modified_date" / "-last_modified_date").
	Ordering string

	// Extra forwards arbitrary query params that don't have a typed field.
	Extra map[string]any
}

EntitySubawardsOptions filters /api/entities/{uei}/subawards/. The subawards endpoint enforces a strict server-side ordering allowlist (see tango#2254); pass values through as-is and let the server validate.

type EntitySubresourceOptions

type EntitySubresourceOptions struct {
	ListOptions

	// Joiner is the separator used when flat=true to join nested keys.
	// Default on the server side is ".". Only meaningful when Flat is set.
	Joiner string

	// Ordering is the server-side sort spec. Endpoint-specific allowlist;
	// prefix with "-" for descending.
	Ordering string

	// Search is a free-text search filter where supported by the endpoint.
	Search string

	// Extra forwards arbitrary query params that don't have a typed field.
	Extra map[string]any
}

EntitySubresourceOptions controls filtering and shaping for the entity sub-resource list endpoints that share a common parameter set: /api/entities/{uei}/contracts/, /idvs/, /otas/, /otidvs/.

Mirrors the Node SDK EntitySubresourceOptions interface.

type GetEntityOptions

type GetEntityOptions struct {
	Shape     string
	Flat      bool
	FlatLists bool
}

GetEntityOptions controls shaping for GetEntity.

type Iterator

type Iterator[T any] struct {
	// contains filtered or unexported fields
}

Iterator walks every result of a paginated list endpoint, following either page= or cursor= on the server's Next URL.

Usage:

iter := client.IterateContracts(ctx, &tango.ListContractsOptions{
    AwardingAgency: "9700",
})
for iter.Next() {
    contract := iter.Item()
    // ...
}
if err := iter.Err(); err != nil { ... }

func (*Iterator[T]) Err

func (it *Iterator[T]) Err() error

Err returns the error that ended iteration, if any.

func (*Iterator[T]) Item

func (it *Iterator[T]) Item() T

Item returns the current item. Only valid after a true return from Next.

func (*Iterator[T]) Next

func (it *Iterator[T]) Next() bool

Next advances the iterator and returns true if Item() is now valid. Returns false when the iteration is finished or an error occurred (in which case Err() returns the error).

func (*Iterator[T]) Seq

func (it *Iterator[T]) Seq() iter.Seq2[T, error]

Seq adapts the iterator to a Go 1.23+ range-over-func sequence. Yields (item, nil) for each result and (zero, err) once if iteration fails. The Next/Item/Err surface still works — Seq is additive sugar.

Usage:

for record, err := range client.IterateContracts(ctx, opts).Seq() {
    if err != nil {
        return err
    }
    // use record
}

Break out of the loop normally; the underlying iterator stops fetching pages as soon as the range body returns false.

type ListAgenciesOptions

type ListAgenciesOptions struct {
	Page   int
	Limit  int
	Search string
}

ListAgenciesOptions filters /api/agencies/.

type ListContractsOptions

type ListContractsOptions struct {
	ListOptions

	// Date / FY / dollar bounds
	AwardDate     string
	AwardDateGte  string
	AwardDateLte  string
	AwardType     string
	FiscalYear    string // accept as string to allow "2024" / "FY24" / range expressions
	FiscalYearGte string
	FiscalYearLte string
	ObligatedGte  string
	ObligatedLte  string

	// Period of performance / expiring
	PopStartDateGte string
	PopStartDateLte string
	PopEndDateGte   string
	PopEndDateLte   string
	ExpiringGte     string
	ExpiringLte     string

	// Agencies / identifiers
	AwardingAgency         string
	FundingAgency          string
	PIID                   string
	SolicitationIdentifier string
	NAICS                  string
	PSC                    string
	Recipient              string
	UEI                    string
	SetAside               string

	// SDK-friendly aliases (mirror Node/Python)
	NAICSCode     string // -> naics
	PSCCode       string // -> psc
	RecipientName string // -> recipient
	RecipientUEI  string // -> uei
	SetAsideType  string // -> set_aside

	// Search + ordering
	Search   string
	Keyword  string // -> search
	Ordering string
	Sort     string // combined with Order -> ordering
	Order    string // "asc" | "desc"

	// Extra is an escape hatch for filter keys not yet first-classed on
	// this struct. Values are stringified with fmt.Sprint.
	Extra map[string]any
}

ListContractsOptions are the filters and pagination params accepted by ListContracts. All fields are optional; embed ListOptions for pagination + shape control. SDK-friendly aliases (KeywordSearch, RecipientName, NAICSCode, PSCCode, RecipientUEI, SetAsideType) map to the canonical API names — passing both prefers the SDK alias to mirror the Node/Python SDKs.

type ListEntitiesOptions

type ListEntitiesOptions struct {
	ListOptions

	Search                    string
	CageCode                  string
	NAICS                     string
	Name                      string
	PSC                       string
	PurposeOfRegistrationCode string
	Socioeconomic             string
	State                     string
	TotalAwardsObligatedGte   string
	TotalAwardsObligatedLte   string
	UEI                       string
	ZipCode                   string

	Extra map[string]any
}

ListEntitiesOptions filters /api/entities/ (federal vendors / recipients).

type ListForecastsOptions

type ListForecastsOptions struct {
	ListOptions

	Agency          string
	AwardDateAfter  string
	AwardDateBefore string
	FiscalYear      string
	FiscalYearGte   string
	FiscalYearLte   string
	ModifiedAfter   string
	ModifiedBefore  string
	NAICSCode       string
	NAICSStartsWith string
	Ordering        string
	Search          string
	SourceSystem    string
	Status          string

	Extra map[string]any
}

ListForecastsOptions filters /api/forecasts/.

type ListGrantsOptions

type ListGrantsOptions struct {
	ListOptions

	Agency             string
	ApplicantTypes     string
	CFDANumber         string
	FundingCategories  string
	FundingInstruments string
	OpportunityNumber  string
	Ordering           string
	PostedDateAfter    string
	PostedDateBefore   string
	ResponseDateAfter  string
	ResponseDateBefore string
	Search             string
	Status             string

	Extra map[string]any
}

ListGrantsOptions filters /api/grants/.

type ListGsaElibraryContractsOptions

type ListGsaElibraryContractsOptions struct {
	ListOptions

	Schedule       string
	ContractNumber string
	Key            string
	PIID           string
	UEI            string
	SIN            string
	Search         string
	Ordering       string

	Extra map[string]any
}

ListGsaElibraryContractsOptions filters /api/gsa_elibrary_contracts/. Mirrors the Node `ListGsaElibraryContractsOptions` interface and the Python `list_gsa_elibrary_contracts` kwargs.

type ListIDVsOptions

type ListIDVsOptions struct {
	ListOptions

	AwardDate              string
	AwardDateGte           string
	AwardDateLte           string
	AwardingAgency         string
	FundingAgency          string
	ExpiringGte            string
	ExpiringLte            string
	FiscalYear             string
	FiscalYearGte          string
	FiscalYearLte          string
	IDVType                string
	LastDateToOrderGte     string
	LastDateToOrderLte     string
	NAICS                  string
	Ordering               string
	PIID                   string
	PopStartDateGte        string
	PopStartDateLte        string
	PSC                    string
	Recipient              string
	Search                 string
	SetAside               string
	SolicitationIdentifier string
	UEI                    string

	Extra map[string]any
}

ListIDVsOptions filters /api/idvs/ (Indefinite Delivery Vehicles).

type ListItDashboardOptions

type ListItDashboardOptions struct {
	ListOptions

	Search           string
	AgencyCode       string // accept string to allow numeric or text codes
	AgencyName       string
	TypeOfInvestment string

	// Date / timestamp bounds (wire: ISO 8601).
	UpdatedTimeAfter  string
	UpdatedTimeBefore string

	// CIO ratings + performance risk. Accept strings for flexibility
	// (the API accepts both "3" and integer-typed values; keeping
	// strings avoids ambiguity around "unset" for numeric zero).
	CIORating       string
	CIORatingMax    string
	PerformanceRisk string

	Extra map[string]any
}

ListItDashboardOptions filters /api/itdashboard/ — federal IT investments from the IT Dashboard. Mirrors the Node `ListItDashboardOptions` interface and the Python `list_itdashboard_investments` kwargs.

Filters are tier-gated by the API:

  • Free: Search
  • Pro: AgencyCode, TypeOfInvestment, UpdatedTimeAfter, UpdatedTimeBefore
  • Business+: AgencyName, CIORating, CIORatingMax, PerformanceRisk

Hitting a gated filter on a lower tier returns a 403.

CIO ratings: 1=High Risk, 2=Moderately High, 3=Medium, 4=Moderately Low, 5=Low.

type ListLcatsOptions

type ListLcatsOptions struct {
	// UEI dispatches to /api/entities/{uei}/lcats/.
	UEI string

	// IDVKey dispatches to /api/idvs/{key}/lcats/.
	IDVKey string

	// Sub-resource filters: shape / pagination / search / ordering.
	// These are forwarded to the dispatched endpoint as-is.
	EntityLcatsOptions
}

ListLcatsOptions selects which owner's Labor Categories (LCATs) to list. Exactly one of UEI or IDVKey must be set — LCATs live under owner resources in the Tango API; there is no top-level `/api/lcats/` endpoint. Mirrors the Node SDK's `listLcats` dispatcher.

If both UEI and IDVKey are set, UEI wins.

type ListMasSinsOptions

type ListMasSinsOptions struct {
	ListOptions

	// Search is a free-text query against the SIN number, title, and
	// description.
	Search string
}

ListMasSinsOptions filters /api/mas_sins/. Embeds ListOptions for pagination + shape control; adds a Search knob.

type ListMetricsOptions

type ListMetricsOptions struct {
	// OwnerType is one of "naics", "psc", or "entity" (see the
	// MetricsOwner* constants).
	OwnerType string

	// OwnerID is the code/UEI of the owner: NAICS code, PSC code, or
	// entity UEI.
	OwnerID string

	// Months is the rolling-window length in months. Must be > 0.
	Months int

	// PeriodGrouping is the aggregation granularity for the window —
	// typically "month", "quarter", or "year". Free-text in the path;
	// path-escaped by the client.
	PeriodGrouping string
}

ListMetricsOptions selects an owner (NAICS code, PSC code, or entity UEI) and the rolling-window parameters for the metrics endpoint.

Metrics live under three distinct owner paths in the API:

  • /api/naics/{code}/metrics/{months}/{period_grouping}/
  • /api/psc/{code}/metrics/{months}/{period_grouping}/
  • /api/entities/{uei}/metrics/{months}/{period_grouping}/

ListMetrics is a thin dispatcher over the three typed wrappers (GetNAICSMetrics, GetPSCMetrics, GetEntityMetrics).

type ListNAICSOptions

type ListNAICSOptions struct {
	ListOptions
	Search           string
	RevenueLimit     string
	EmployeeLimit    string
	RevenueLimitGte  string
	RevenueLimitLte  string
	EmployeeLimitGte string
	EmployeeLimitLte string
}

ListNAICSOptions filters /api/naics/.

type ListNoticesOptions

type ListNoticesOptions struct {
	ListOptions

	Active                 *bool
	Agency                 string
	NAICS                  string
	NoticeType             string
	PostedDateAfter        string
	PostedDateBefore       string
	PSC                    string
	ResponseDeadlineAfter  string
	ResponseDeadlineBefore string
	Search                 string
	SetAside               string
	SolicitationNumber     string

	Extra map[string]any
}

ListNoticesOptions filters /api/notices/. The notices viewset rejects every ?ordering= value, so it isn't exposed here (mirrors Python/Node).

type ListOTAsOptions

type ListOTAsOptions struct {
	ListOptions

	// Joiner is the separator used when Flat is true (e.g. "." or "__").
	// Empty means "use the server default".
	Joiner string

	// Identifiers + agencies
	AwardingAgency string
	FundingAgency  string
	PIID           string
	Recipient      string
	UEI            string

	// Dollar / fiscal-year bounds
	FiscalYear    string
	FiscalYearGte string
	FiscalYearLte string

	// Date bounds
	AwardDate       string
	AwardDateGte    string
	AwardDateLte    string
	ExpiringGte     string
	ExpiringLte     string
	PopStartDateGte string
	PopStartDateLte string
	PopEndDateGte   string
	PopEndDateLte   string

	// Classification
	PSC string

	// Search + ordering
	Search   string
	Ordering string

	// Extra is an escape hatch for filter keys not first-classed here.
	Extra map[string]any
}

ListOTAsOptions filters /api/otas/ (Other Transaction Authority award actions). Mirror of the Node `ListOTAsOptions` interface and the Python `list_otas` kwargs.

All date / fiscal-year fields are wire-format strings (see the SDK design note: dates stay strings to match the API). Empty fields are omitted from the request.

type ListOTIDVAwardsOptions

type ListOTIDVAwardsOptions struct {
	ListOptions

	Joiner string

	AwardingAgency string
	FundingAgency  string
	PIID           string
	Recipient      string
	UEI            string

	FiscalYear    string
	FiscalYearGte string
	FiscalYearLte string

	AwardDate       string
	AwardDateGte    string
	AwardDateLte    string
	ExpiringGte     string
	ExpiringLte     string
	PopStartDateGte string
	PopStartDateLte string
	PopEndDateGte   string
	PopEndDateLte   string

	PSC string

	Search   string
	Ordering string

	Extra map[string]any
}

ListOTIDVAwardsOptions filters /api/otidvs/{key}/awards/. Same filter shape as ListOTAsOptions per the Node interface.

type ListOTIDVsOptions

type ListOTIDVsOptions struct {
	ListOptions

	Joiner string

	AwardingAgency string
	FundingAgency  string
	PIID           string
	Recipient      string
	UEI            string

	FiscalYear    string
	FiscalYearGte string
	FiscalYearLte string

	AwardDate       string
	AwardDateGte    string
	AwardDateLte    string
	ExpiringGte     string
	ExpiringLte     string
	PopStartDateGte string
	PopStartDateLte string
	PopEndDateGte   string
	PopEndDateLte   string

	PSC string

	Search   string
	Ordering string

	Extra map[string]any
}

ListOTIDVsOptions filters /api/otidvs/ (Other Transaction IDV parents). Same filter set as ListOTAsOptions per the sibling SDKs.

type ListOfficesOptions

type ListOfficesOptions struct {
	ListOptions

	// Search is a free-text query matched against office name + code.
	Search string
}

ListOfficesOptions filters /api/offices/. Embeds ListOptions for pagination + shape control; adds a Search knob to full-text-search office names and codes.

type ListOpportunitiesOptions

type ListOpportunitiesOptions struct {
	ListOptions

	Active                 *bool
	Agency                 string
	FirstNoticeDateAfter   string
	FirstNoticeDateBefore  string
	LastNoticeDateAfter    string
	LastNoticeDateBefore   string
	NAICS                  string
	NoticeType             string
	Ordering               string
	PlaceOfPerformance     string
	PSC                    string
	ResponseDeadlineAfter  string
	ResponseDeadlineBefore string
	Search                 string
	SetAside               string
	SolicitationNumber     string

	Extra map[string]any
}

ListOpportunitiesOptions filters /api/opportunities/.

type ListOptions

type ListOptions struct {
	// Page is 1-based and used for offset-paginated endpoints. Mutually
	// exclusive with Cursor; if both are set, Cursor wins.
	Page int

	// Limit is the page size. The server caps this at 100 on most
	// endpoints. 0 means "use the server default".
	Limit int

	// Cursor is the keyset cursor for cursor-paginated endpoints (most
	// list endpoints support it). Pass the Cursor field from the
	// previous response.
	Cursor string

	// Shape is the comma-separated field selector for dynamic response
	// shaping. Use one of the Shape* constants or roll your own. Empty
	// means "use the API default for this endpoint".
	Shape string

	// Flat collapses nested objects into dot-separated keys in the
	// response. Default false.
	Flat bool

	// FlatLists when true flattens list-valued nested fields as well.
	// Only meaningful when Flat is true.
	FlatLists bool
}

ListOptions is the shared embed for every list endpoint. Per-resource options structs embed this so callers can set pagination + shaping on any list call.

type ListOrganizationsOptions

type ListOrganizationsOptions struct {
	ListOptions
	Search          string
	Type            string
	Level           string
	CGAC            string
	Parent          string
	IncludeInactive *bool
}

ListOrganizationsOptions filters /api/organizations/.

type ListProtestsOptions

type ListProtestsOptions struct {
	ListOptions

	SourceSystem       string
	Outcome            string
	CaseType           string
	Agency             string
	CaseNumber         string
	SolicitationNumber string
	Protester          string
	Search             string

	// Date bounds (wire format: YYYY-MM-DD). Note the
	// `_after` / `_before` suffix convention — unique to protests; the
	// Python client uses these exact names.
	FiledDateAfter     string
	FiledDateBefore    string
	DecisionDateAfter  string
	DecisionDateBefore string

	Extra map[string]any
}

ListProtestsOptions filters /api/protests/. Mirrors the Node `ListProtestsOptions` interface and the Python `list_protests` kwargs.

The protests viewset does not accept ordering (the server rejects it), so this struct intentionally omits an Ordering field.

type ListSubawardsOptions

type ListSubawardsOptions struct {
	ListOptions
	AwardKey       string
	PrimeUEI       string
	SubUEI         string
	AwardingAgency string
	FundingAgency  string
	FiscalYear     string
	FiscalYearGte  string
	FiscalYearLte  string
	Recipient      string
	// Ordering must be "last_modified_date" or "-last_modified_date";
	// the server rejects others (tango#2254).
	Ordering string
}

ListSubawardsOptions filters /api/subawards/.

type ListVehiclesOptions

type ListVehiclesOptions struct {
	ListOptions

	Joiner                string
	Search                string
	VehicleType           string
	TypeOfIDC             string
	ContractType          string
	SetAside              string
	WhoCanUse             string
	NAICSCode             string
	PSCCode               string
	ProgramAcronym        string
	Agency                string
	OrganizationID        string
	TotalObligatedMin     string
	TotalObligatedMax     string
	IDVCountMin           int
	IDVCountMax           int
	OrderCountMin         int
	OrderCountMax         int
	FiscalYear            string
	AwardDateAfter        string
	AwardDateBefore       string
	LastDateToOrderAfter  string
	LastDateToOrderBefore string
	// Server enforces a strict ordering allowlist; other values 400.
	Ordering string

	Extra map[string]any
}

ListVehiclesOptions filters /api/vehicles/ (contracting vehicles).

type NotFoundError

type NotFoundError struct{ *APIError }

NotFoundError is raised on HTTP 404.

func (*NotFoundError) Error

func (e *NotFoundError) Error() string

Error implements the error interface.

func (*NotFoundError) Unwrap

func (e *NotFoundError) Unwrap() error

Unwrap returns the embedded *APIError so errors.As / errors.Is can traverse to the base error type.

type Option

type Option func(*clientConfig)

Option configures a Client. Pass any number of these to NewClient.

func WithAPIKey

func WithAPIKey(key string) Option

WithAPIKey sets the Tango API key. When omitted, the client reads the TANGO_API_KEY environment variable. Passing an explicit empty string is equivalent to not passing this option.

func WithBaseURL

func WithBaseURL(url string) Option

WithBaseURL overrides the API base URL. Precedence: this option > TANGO_BASE_URL env var > DefaultBaseURL.

func WithHTTPClient

func WithHTTPClient(hc *http.Client) Option

WithHTTPClient supplies a custom *http.Client. Useful for injecting custom transports (proxies, tracing, etc.). The client's Timeout field is ignored — request deadlines are managed via context.

func WithRetries

func WithRetries(n int) Option

WithRetries sets the number of retry attempts on retryable failures (5xx, 408, 429, transport errors). The initial attempt is not counted as a retry, so the total attempt count is retries + 1. Defaults to 3.

func WithRetryBackoff

func WithRetryBackoff(d time.Duration) Option

WithRetryBackoff sets the initial backoff for retries. The actual wait doubles each retry, capped at 10s. The server's Retry-After header (when present on 429/503) overrides this. Defaults to 250ms.

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout sets the per-request timeout. Defaults to 30s. A timeout of 0 disables the deadline (matching net/http semantics).

func WithUserAgent

func WithUserAgent(ua string) Option

WithUserAgent sets a custom User-Agent header. Defaults to "tango-go/<version>".

type PaginatedResponse

type PaginatedResponse[T any] struct {
	// Count is the total number of items across all pages, when the
	// server reports it. For some endpoints this matches len(Results).
	Count int `json:"count"`

	// Next is the URL of the next page, or "" when on the last page.
	Next string `json:"next"`

	// Previous is the URL of the previous page, or "" when on the first.
	Previous string `json:"previous"`

	// PageMetadata carries opaque page metadata for keyset endpoints.
	PageMetadata map[string]any `json:"page_metadata,omitempty"`

	// Cursor is the cursor extracted from Next on keyset-paginated
	// endpoints. Pass it back via the Cursor option to fetch the next
	// page. Empty when the endpoint is page-based or no cursor is set.
	Cursor string `json:"-"`

	// Results is the actual data for this page.
	Results []T `json:"results"`
}

PaginatedResponse is the standard envelope for list endpoints.

For keyset/cursor endpoints (e.g. /api/idvs/), the next cursor is extracted from Next for convenience and exposed on Cursor.

type ProtestRecord

type ProtestRecord struct {
	CaseID            string           `json:"case_id,omitempty"`
	CaseNumber        string           `json:"case_number,omitempty"`
	SourceSystem      string           `json:"source_system,omitempty"`
	Outcome           string           `json:"outcome,omitempty"`
	CaseType          string           `json:"case_type,omitempty"`
	FiledDate         string           `json:"filed_date,omitempty"`
	DecisionDate      string           `json:"decision_date,omitempty"`
	Agency            map[string]any   `json:"agency,omitempty"`
	Protester         map[string]any   `json:"protester,omitempty"`
	ResolvedAgency    map[string]any   `json:"resolved_agency,omitempty"`
	ResolvedProtester map[string]any   `json:"resolved_protester,omitempty"`
	Docket            []map[string]any `json:"docket,omitempty"`

	// Extra captures any additional fields returned by the API that
	// aren't first-classed above. Populated by callers who need to
	// preserve unknown fields when re-marshaling; not auto-populated
	// from JSON.
	Extra map[string]any `json:"-"`
}

ProtestRecord is the typed return model for GetProtest. Mirrors the canonical GAO / Court of Federal Claims protest case schema as defined in tango-node/src/types.ts:137-151.

All fields except Docket are optional (protests come from multiple source systems and not every field is always populated). Extra captures any wire fields not first-classed on the struct so callers don't lose them — the same pattern used by the request-options structs in this package.

Note: this is implementer-B's local typed model; tango-go may consolidate typed records into a shared models.go in a later wave.

type RateLimitError

type RateLimitError struct {
	*APIError
	// RetryAfter is the server-suggested wait before retrying, in seconds.
	// 0 when the Retry-After header is absent or unparseable.
	RetryAfter int
	// LimitType is the value of X-RateLimit-Type when set by the server
	// (used to distinguish per-minute / per-hour / per-day buckets). Empty
	// when absent.
	LimitType string
}

RateLimitError is raised on HTTP 429. RetryAfter is populated from the Retry-After header when present (in seconds).

func (*RateLimitError) Error

func (e *RateLimitError) Error() string

Error implements the error interface.

func (*RateLimitError) Unwrap

func (e *RateLimitError) Unwrap() error

Unwrap returns the embedded *APIError so errors.As / errors.Is can traverse to the base error type.

type RateLimitInfo

type RateLimitInfo struct {
	Remaining  int    // -1 when header was absent or unparseable
	Limit      int    // -1 when absent
	ResetIn    int    // seconds; -1 when absent
	RetryAfter int    // seconds; -1 when absent
	LimitType  string // empty when absent
}

RateLimitInfo is a snapshot of the rate-limit headers from the most recent response. Mirrors Python's RateLimitInfo dataclass.

type Record

type Record = map[string]any

Record is the default result type for list endpoints. It mirrors the permissive map[string]any shape used by the API — fields vary based on the requested shape, so callers either work with the map directly or json.Unmarshal it into their own struct.

type ResolveCandidate

type ResolveCandidate struct {
	// Identifier is the canonical UEI (when TargetType is "entity") or
	// organization key (when TargetType is "organization").
	Identifier string `json:"identifier,omitempty"`

	// DisplayName is the human-readable name of the candidate.
	DisplayName string `json:"display_name,omitempty"`

	// MatchTier is the confidence label ("low" | "medium" | "high").
	// Pro+ tiers only — Free responses omit this.
	MatchTier string `json:"match_tier,omitempty"`

	// Extra holds any additional server-supplied metadata.
	Extra map[string]any `json:"extra,omitempty"`
}

ResolveCandidate is a single candidate returned by Resolve.

type ResolveInput

type ResolveInput struct {
	Name       string            `json:"name"`
	TargetType ResolveTargetType `json:"target_type"`
	State      string            `json:"state,omitempty"`
	City       string            `json:"city,omitempty"`
	Context    string            `json:"context,omitempty"`
}

ResolveInput is the body POSTed to /api/resolve/.

type ResolveResult

type ResolveResult struct {
	// Count is the number of candidates returned (capped by tier:
	// Free=3, Pro+=5).
	Count      int                `json:"count,omitempty"`
	Candidates []ResolveCandidate `json:"candidates"`
}

ResolveResult is the response from /api/resolve/.

type ResolveTargetType

type ResolveTargetType string

ResolveTargetType selects the resource the resolver searches against.

const (
	// ResolveEntity targets the entity (SAM.gov vendor) resolver.
	ResolveEntity ResolveTargetType = "entity"
	// ResolveOrganization targets the federal organization resolver
	// (departments / agencies / sub-agencies / offices).
	ResolveOrganization ResolveTargetType = "organization"
)

type SearchOpportunityAttachmentsOptions

type SearchOpportunityAttachmentsOptions struct {
	// Q is the natural-language query. Required; client-side validated
	// (empty Q raises *ValidationError before any network call).
	Q string

	// TopK is the maximum number of matches to return. 0 means
	// "use the server default".
	TopK int

	// IncludeExtractedText, when true, returns the matched attachment
	// text alongside the metadata. False / unset omits the text payload
	// to keep responses small.
	IncludeExtractedText bool
}

SearchOpportunityAttachmentsOptions controls the /api/opportunities/attachment-search/ endpoint — semantic search over the extracted text of opportunity attachments (SOWs, PWSs, J&As, etc.).

Q is required. TopK and IncludeExtractedText are optional and mirror the Node + Python options of the same names.

type TimeoutError

type TimeoutError struct{ *APIError }

TimeoutError is raised when a request exceeds the configured timeout. StatusCode is 0.

func (*TimeoutError) Error

func (e *TimeoutError) Error() string

Error implements the error interface.

func (*TimeoutError) Unwrap

func (e *TimeoutError) Unwrap() error

Unwrap returns the embedded *APIError so errors.As / errors.Is can traverse to the base error type.

type ValidateInput

type ValidateInput struct {
	Type  ValidateInputType `json:"type"`
	Value string            `json:"value"`
}

ValidateInput is the body POSTed to /api/validate/.

type ValidateInputType

type ValidateInputType string

ValidateInputType is the identifier type checked by Validate.

const (
	// ValidatePIID validates the format of a PIID / contract identifier.
	ValidatePIID ValidateInputType = "piid"
	// ValidateSolicitation validates the format of a solicitation number.
	ValidateSolicitation ValidateInputType = "solicitation"
	// ValidateUEI validates the format and check digits of a UEI.
	ValidateUEI ValidateInputType = "uei"
)

type ValidateResult

type ValidateResult struct {
	// Result is "valid", "invalid", or "low_confidence".
	Result string `json:"result"`
	Type   string `json:"type,omitempty"`
	Value  string `json:"value,omitempty"`
	// Errors carries structured failures when Result is non-valid.
	Errors []map[string]any `json:"errors,omitempty"`
}

ValidateResult is the response from /api/validate/.

type ValidationError

type ValidationError struct{ *APIError }

ValidationError is raised on HTTP 400 (or other client-supplied invalid input that the SDK rejects locally).

func (*ValidationError) Error

func (e *ValidationError) Error() string

Error implements the error interface.

func (*ValidationError) Unwrap

func (e *ValidationError) Unwrap() error

Unwrap returns the embedded *APIError so errors.As / errors.Is can traverse to the base error type.

type WebhookAlert

type WebhookAlert struct {
	AlertID        *string        `json:"alert_id,omitempty"`
	Name           *string        `json:"name,omitempty"`
	QueryType      *string        `json:"query_type,omitempty"`
	Filters        map[string]any `json:"filters,omitempty"`
	Frequency      *string        `json:"frequency,omitempty"`
	CronExpression *string        `json:"cron_expression,omitempty"`
	Status         *string        `json:"status,omitempty"`
	CreatedAt      *string        `json:"created_at,omitempty"`
	LastCheckedAt  *string        `json:"last_checked_at,omitempty"`
	MatchCount     *int           `json:"match_count,omitempty"`

	Extra map[string]any `json:"-"`
}

WebhookAlert is a filter-based subscription. Mirrors `WebhookAlert` in `tango-node/src/models/Webhooks.ts`. Note that the alerts API uses `name` + `filters` (whereas the canonical subscriptions API uses `subscription_name` + `filter_definition`); see the Node model file for the rationale.

func (*WebhookAlert) UnmarshalJSON

func (w *WebhookAlert) UnmarshalJSON(data []byte) error

UnmarshalJSON catches forward-compatible fields into Extra.

type WebhookAlertCreateInput

type WebhookAlertCreateInput struct {
	Name           string         `json:"name"`
	QueryType      string         `json:"query_type"`
	Filters        map[string]any `json:"filters"`
	Frequency      *string        `json:"frequency,omitempty"`
	CronExpression *string        `json:"cron_expression,omitempty"`
	Endpoint       *string        `json:"endpoint,omitempty"`
}

WebhookAlertCreateInput is the body for CreateWebhookAlert.

`Name`, `QueryType`, and `Filters` are required. `QueryType` is SINGULAR (e.g. `"contract"`, not `"contracts"`). `Endpoint` is the UUID of the destination webhook; required for accounts with multiple endpoints, optional otherwise (the server auto-resolves a single endpoint).

type WebhookAlertUpdateInput

type WebhookAlertUpdateInput struct {
	Name           *string `json:"name,omitempty"`
	Frequency      *string `json:"frequency,omitempty"`
	CronExpression *string `json:"cron_expression,omitempty"`
	IsActive       *bool   `json:"is_active,omitempty"`
}

WebhookAlertUpdateInput is the patch body for UpdateWebhookAlert. Only `name`, `frequency`, `cron_expression`, and `is_active` are writable server-side; `query_type` and `filters` are read-only after creation.

type WebhookEndpoint

type WebhookEndpoint struct {
	ID          *string `json:"id,omitempty"`
	Name        *string `json:"name,omitempty"`
	CallbackURL *string `json:"callback_url,omitempty"`
	Secret      *string `json:"secret,omitempty"`
	IsActive    *bool   `json:"is_active,omitempty"`
	CreatedAt   *string `json:"created_at,omitempty"`
	UpdatedAt   *string `json:"updated_at,omitempty"`

	Extra map[string]any `json:"-"`
}

WebhookEndpoint is a configured outbound webhook destination. Mirrors the `WebhookEndpoint` interface in `tango-node/src/models/Webhooks.ts`.

func (*WebhookEndpoint) UnmarshalJSON

func (w *WebhookEndpoint) UnmarshalJSON(data []byte) error

UnmarshalJSON catches forward-compatible fields into Extra.

type WebhookEndpointCreateInput

type WebhookEndpointCreateInput struct {
	Name        string   `json:"name"`
	CallbackURL string   `json:"callback_url"`
	IsActive    *bool    `json:"is_active,omitempty"`
	EventTypes  []string `json:"event_types,omitempty"`
}

WebhookEndpointCreateInput is the body for CreateWebhookEndpoint.

`Name` and `CallbackURL` are required server-side (the API enforces unique(user, name) on endpoints — see tango#1.0.0 changes). `IsActive` defaults to true on the server when omitted; the SDK preserves omit semantics so the server gets to apply that default.

type WebhookEndpointUpdateInput

type WebhookEndpointUpdateInput struct {
	Name        *string  `json:"name,omitempty"`
	CallbackURL *string  `json:"callback_url,omitempty"`
	IsActive    *bool    `json:"is_active,omitempty"`
	EventTypes  []string `json:"event_types,omitempty"`
}

WebhookEndpointUpdateInput is the patch body for UpdateWebhookEndpoint. All fields are optional; only the ones the caller sets are sent to the server.

type WebhookEventType

type WebhookEventType struct {
	EventType     *string `json:"event_type,omitempty"`
	Description   *string `json:"description,omitempty"`
	SchemaVersion *int    `json:"schema_version,omitempty"`

	Extra map[string]any `json:"-"`
}

WebhookEventType describes a single event type the server can emit.

func (*WebhookEventType) UnmarshalJSON

func (w *WebhookEventType) UnmarshalJSON(data []byte) error

UnmarshalJSON catches forward-compatible fields into Extra.

type WebhookEventTypesResponse

type WebhookEventTypesResponse struct {
	EventTypes []WebhookEventType `json:"event_types,omitempty"`

	Extra map[string]any `json:"-"`
}

WebhookEventTypesResponse wraps the response from ListWebhookEventTypes.

func (*WebhookEventTypesResponse) UnmarshalJSON

func (w *WebhookEventTypesResponse) UnmarshalJSON(data []byte) error

UnmarshalJSON catches forward-compatible fields into Extra.

type WebhookSampleDelivery

type WebhookSampleDelivery struct {
	Timestamp *string          `json:"timestamp,omitempty"`
	Events    []map[string]any `json:"events,omitempty"`

	Extra map[string]any `json:"-"`
}

WebhookSampleDelivery is one element of a sample-payload response body — a timestamped batch of synthetic events the server will deliver.

func (*WebhookSampleDelivery) UnmarshalJSON

func (w *WebhookSampleDelivery) UnmarshalJSON(data []byte) error

UnmarshalJSON catches forward-compatible fields into Extra.

type WebhookSamplePayloadResponse

type WebhookSamplePayloadResponse struct {
	// Single-event-type variant fields:
	EventType       *string                `json:"event_type,omitempty"`
	SampleDelivery  *WebhookSampleDelivery `json:"sample_delivery,omitempty"`
	SignatureHeader *string                `json:"signature_header,omitempty"`
	Note            *string                `json:"note,omitempty"`

	// All-types variant fields:
	Samples map[string]struct {
		SampleDelivery *WebhookSampleDelivery `json:"sample_delivery,omitempty"`
	} `json:"samples,omitempty"`
	Usage *string `json:"usage,omitempty"`

	Extra map[string]any `json:"-"`
}

WebhookSamplePayloadResponse covers both variants returned by `/api/webhooks/endpoints/sample-payload/`: the single-event-type variant (when `event_type` is passed) and the all-types variant (when it is not). Callers can branch on which fields are populated. Mirrors the union `WebhookSamplePayloadSingleResponse | WebhookSamplePayloadAllResponse` in `tango-node/src/models/Webhooks.ts`.

func (*WebhookSamplePayloadResponse) UnmarshalJSON

func (w *WebhookSamplePayloadResponse) UnmarshalJSON(data []byte) error

UnmarshalJSON catches forward-compatible fields into Extra.

type WebhookTestDeliveryResult

type WebhookTestDeliveryResult struct {
	Success        *bool          `json:"success,omitempty"`
	StatusCode     *int           `json:"status_code,omitempty"`
	ResponseTimeMs *int           `json:"response_time_ms,omitempty"`
	EndpointURL    *string        `json:"endpoint_url,omitempty"`
	Message        *string        `json:"message,omitempty"`
	Error          *string        `json:"error,omitempty"`
	ResponseBody   *string        `json:"response_body,omitempty"`
	TestPayload    map[string]any `json:"test_payload,omitempty"`

	Extra map[string]any `json:"-"`
}

WebhookTestDeliveryResult is the response from TestWebhookEndpoint.

func (*WebhookTestDeliveryResult) UnmarshalJSON

func (w *WebhookTestDeliveryResult) UnmarshalJSON(data []byte) error

UnmarshalJSON catches forward-compatible fields into Extra.

Directories

Path Synopsis
examples
iterate-entities command
iterate-entities walks every entity matching a NAICS filter, printing the UEI and legal business name.
iterate-entities walks every entity matching a NAICS filter, printing the UEI and legal business name.
list-contracts command
list-contracts is a tiny example that prints the most recent DoD contracts using the Tango Go SDK.
list-contracts is a tiny example that prints the most recent DoD contracts using the Tango Go SDK.
webhook-server command
webhook-server is a minimal HTTP server that verifies Tango webhook signatures and prints the delivered payload.
webhook-server is a minimal HTTP server that verifies Tango webhook signatures and prints the delivered payload.
Package webhooks provides HMAC-SHA256 signing and verification for Tango webhook deliveries.
Package webhooks provides HMAC-SHA256 signing and verification for Tango webhook deliveries.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL