pactman

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Sep 25, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package pactman is the official Go client for the Pactman Nonprofit Check Plus API: look up US nonprofits by EIN and read the IRS and OFAC findings behind the result.

Server-side only — the API key is a private credential.

client, err := pactman.NewClient(os.Getenv("PACTMAN_API_KEY"))
if err != nil {
	return err
}

result, err := client.Nonprofits.Check(ctx, "41-1787097")
if err != nil {
	return err
}

if result.Nonprofit != nil {
	fmt.Println(*result.Nonprofit.OrganizationName, *result.CheckCount)
}

Errors

Every error is an Error with a stable ErrorCategory and ErrorOrigin. Branch with errors.Is on the Err* sentinels, or errors.As on the concrete types — never on message text:

var apiErr *pactman.APIError
switch {
case errors.Is(err, pactman.ErrValidation):  // bad input; nothing was sent
case errors.Is(err, pactman.ErrRateLimit):   // apiErr.RetryAfter, when sent
case errors.As(err, &apiErr):                // any other HTTP failure
}

What this package does not tell you

It exposes what the API returns and nothing more: no composite approved, eligible or safe verdict, and no boolean summarizing a source the API does not itself express as a boolean. A successful check is data, not a decision.

Index

Constants

View Source
const BulkCheckPath = "/api/entities/nonprofitcheckbulk/v1/us/eins"

BulkCheckPath is the path of the bulk-check endpoint.

View Source
const DefaultEnvironment = EnvironmentProduction

DefaultEnvironment is the environment used when none is configured.

View Source
const DefaultTimeout = 30 * time.Second

DefaultTimeout is the per-attempt timeout used when none is configured. The timeout is always finite; there is no way to disable it.

View Source
const EINLength = 9

EINLength is the number of digits in an EIN.

View Source
const MaxBulkEINs = 50

MaxBulkEINs is the most EINs the API accepts in one bulk request. It mirrors the server-side limit and is declared once, here.

View Source
const PackageName = "pactman-nonprofit-check-plus"

PackageName is the distribution name reported in the User-Agent header. It matches the name the other Pactman SDKs report, with the runtime telling them apart.

View Source
const SingleCheckPath = "/api/entities/nonprofitcheck/v1/us/ein/{ein}"

SingleCheckPath is the path of the single-check endpoint. {ein} is replaced with a normalized EIN.

View Source
const Version = "1.0.0"

Version is the released version of this package, reported in the User-Agent header.

A Go module's version is its git tag (go/vX.Y.Z), which the compiled code cannot read. The release workflow fails a tag that disagrees with this constant, so the number a server sees and the number published are the same.

Variables

View Source
var (
	ErrConfiguration  error = &sentinel{CategoryConfiguration}
	ErrValidation     error = &sentinel{CategoryValidation}
	ErrAuthentication error = &sentinel{CategoryAuthentication}
	ErrAuthorization  error = &sentinel{CategoryAuthorization}
	ErrBadRequest     error = &sentinel{CategoryBadRequest}
	ErrNotFound       error = &sentinel{CategoryNotFound}
	ErrRateLimit      error = &sentinel{CategoryRateLimit}
	ErrServer         error = &sentinel{CategoryServer}
	ErrTimeout        error = &sentinel{CategoryTimeout}
	ErrNetwork        error = &sentinel{CategoryNetwork}
)

Sentinels for errors.Is. Each matches every SDK error of its category:

if errors.Is(err, pactman.ErrNotFound) { ... }

Reach the details with errors.As and the concrete type — *APIError for every HTTP category, *ValidationError, *TimeoutError, *NetworkError, or *ConfigurationError.

Functions

func BaseURLForEnvironment

func BaseURLForEnvironment(environment Environment) (string, error)

BaseURLForEnvironment returns the base URL for a named environment.

func IsValidEIN

func IsValidEIN(input string) bool

IsValidEIN reports whether input is shaped like an EIN.

func NormalizeEIN

func NormalizeEIN(input string) (string, error)

NormalizeEIN normalizes an EIN to the nine-digit form the API expects.

"41-1787097" and "411787097" both normalize to "411787097".

This is formatting validation only. Passing it says nothing about whether an organization is tax-exempt, in good standing, or eligible for anything — only that the value is shaped like an EIN. No IRS prefix rules are applied.

A malformed value returns a *ValidationError.

func NormalizeEINs

func NormalizeEINs(inputs []string) ([]string, error)

NormalizeEINs normalizes a list of EINs, reporting every failure at once.

Order is retained and duplicates are preserved; see WithDedupe for CheckBulk's optional deduplication. A malformed item returns a *ValidationError whose Issues identify each failing item by index and value.

Types

type APIError

type APIError struct {
	// Status is the HTTP status code.
	Status int
	// APIMessage is the envelope's reasons joined, or its message, or the start
	// of a non-JSON body. Empty when the response carried none.
	APIMessage string
	// APICode is the envelope's code, when present.
	APICode *int
	// APIErrors is the envelope's errors, normalized to a list.
	APIErrors []APIErrorDetail
	// RequestID is the correlation identifier from the response headers.
	RequestID string
	// RetryAfter is the server's Retry-After, when it sent a usable value.
	RetryAfter *time.Duration
	// Body is the response body exactly as received. An undecodable body is
	// still evidence.
	Body []byte
	// Attempts is how many attempts were made before this error surfaced.
	Attempts int
	// contains filtered or unexported fields
}

APIError is an error response from the Pactman API. Every HTTP failure is an *APIError; Category says which kind:

400 CategoryBadRequest       401 CategoryAuthentication
403 CategoryAuthorization    404 CategoryNotFound
429 CategoryRateLimit        5xx CategoryServer
anything else                CategoryAPI

Response metadata is kept even when the body could not be decoded.

func (*APIError) Category

func (e *APIError) Category() ErrorCategory

func (*APIError) Error

func (e *APIError) Error() string

func (*APIError) Is

func (e *APIError) Is(target error) bool

func (*APIError) MarshalJSON

func (e *APIError) MarshalJSON() ([]byte, error)

MarshalJSON renders a sanitized form, safe to log. Body is left out.

func (*APIError) Origin

func (e *APIError) Origin() ErrorOrigin

type APIErrorDetail

type APIErrorDetail struct {
	// Resource is the API resource the error came from.
	Resource string `json:"resource"`
	// Reason is the human-readable explanation.
	Reason string `json:"reason"`
	// Code is the status for this specific failure, which may differ from the
	// HTTP status.
	Code *int `json:"code"`
	// EINs are the EINs this error applies to, for bulk requests. The API sends
	// them as a list or as one comma-separated string; both read as a list.
	EINs []string `json:"eins"`

	// Fields is every field the API returned for this entry, exactly as sent.
	Fields Object `json:"-"`
}

APIErrorDetail is one entry from the envelope's errors list.

func (APIErrorDetail) MarshalJSON

func (d APIErrorDetail) MarshalJSON() ([]byte, error)

MarshalJSON returns the entry as the API sent it.

func (*APIErrorDetail) UnmarshalJSON

func (d *APIErrorDetail) UnmarshalJSON(data []byte) error

UnmarshalJSON reads an entry, keeping every field in Fields.

type AROESource

type AROESource struct {
	RevocationCode    *string
	RevocationDate    *string
	ReinstatementDate *string
}

AROESource holds the IRS Automatic Revocation of Exemption findings.

type BMFSource

type BMFSource struct {
	Status                    *bool
	OrganizationName          *string
	EIN                       *string
	ChurchMessage             *string
	Subsection                *string
	SubsectionDescription     *string
	FoundationCode            *string
	FoundationCodeDescription *string
	FoundationTypeCode        *string
	FoundationTypeDescription *string
	Foundation509aStatus      *string
	RulingMonth               *string
	RulingYear                *string
	GroupExemption            *string
	ExemptStatusCode          *string
	FilingReqCode             *string
	MostRecent                *string
}

BMFSource holds the IRS Business Master File findings.

type BulkCheckResult

type BulkCheckResult struct {
	Result
	// Organizations are the records the API matched, in the order it returned
	// them — which is not guaranteed to follow the order supplied. Index them
	// by EIN rather than pairing them positionally.
	Organizations []*Nonprofit
	// NotFoundEINs are the EINs the API reported no record for, collected from
	// Errors. A bulk request where some EINs miss is an HTTP 200, not an error.
	NotFoundEINs []string
}

BulkCheckResult is the result of NonprofitsResource.CheckBulk.

type Client

type Client struct {
	// Nonprofits holds the nonprofit lookups.
	Nonprofits *NonprofitsResource
	// contains filtered or unexported fields
}

Client is the entry point for the SDK.

Build one per process and share it: a Client is safe for concurrent use, reuses connections, and carries the throttle state when a request-per-second ceiling is set.

Server-side use only. The API key is a private credential. No diagnostic surface of a Client — fmt verbs, json.Marshal, slog — contains it.

func NewClient

func NewClient(apiKey string, opts ...ClientOption) (*Client, error)

NewClient builds a client. The API key is required; load it from the environment or a secret manager, never from source:

client, err := pactman.NewClient(os.Getenv("PACTMAN_API_KEY"))

A blank key, or an unusable option, returns a *ConfigurationError before any request is made.

func (*Client) BaseURL

func (c *Client) BaseURL() string

BaseURL returns the resolved base URL every request is sent to.

func (*Client) Environment

func (c *Client) Environment() Environment

Environment returns the named environment in use, or "" when WithBaseURL gave an explicit host.

func (*Client) Format

func (c *Client) Format(f fmt.State, _ rune)

Format keeps every fmt verb free of the API key.

func (*Client) GoString

func (c *Client) GoString() string

GoString keeps %#v free of the API key.

func (*Client) LogValue

func (c *Client) LogValue() slog.Value

LogValue keeps slog output free of the API key.

func (*Client) MarshalJSON

func (c *Client) MarshalJSON() ([]byte, error)

MarshalJSON renders a redacted view of the configuration.

func (*Client) RetryPolicy

func (c *Client) RetryPolicy() RetryPolicy

RetryPolicy returns a copy of the client's retry policy — a starting point for a per-call WithRetryPolicy.

func (*Client) String

func (c *Client) String() string

String identifies the client by its base URL.

func (*Client) Timeout

func (c *Client) Timeout() time.Duration

Timeout returns the per-attempt timeout.

type ClientOption

type ClientOption interface {
	// contains filtered or unexported methods
}

ClientOption configures a Client. Pass it to NewClient.

func WithBaseURL

func WithBaseURL(baseURL string) ClientOption

WithBaseURL sends requests to an explicit host — a mock server, a proxy, or a host Pactman has given you directly — instead of a named environment. It must be an http or https URL.

func WithEnvironment

func WithEnvironment(environment Environment) ClientOption

WithEnvironment selects a named Pactman environment. Production is the default and the only named environment.

func WithHTTPClient

func WithHTTPClient(client HTTPDoer) ClientOption

WithHTTPClient sends requests through your own HTTP client. The default is an *http.Client over http.DefaultTransport. The per-attempt timeout is applied through the request context, so the client needs no timeout of its own.

func WithMaxRequestsPerSecond

func WithMaxRequestsPerSecond(limit float64) ClientOption

WithMaxRequestsPerSecond sets a client-side ceiling on outbound requests. It is off by default. The server's limits are authoritative and may change; treat this as a courtesy throttle, not a guarantee.

type ConfigurationError

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

ConfigurationError reports unusable client options: a blank API key, a malformed base URL, a nonsensical timeout.

func (*ConfigurationError) Category

func (e *ConfigurationError) Category() ErrorCategory

func (*ConfigurationError) Error

func (e *ConfigurationError) Error() string

func (*ConfigurationError) Is

func (e *ConfigurationError) Is(target error) bool

func (*ConfigurationError) MarshalJSON

func (e *ConfigurationError) MarshalJSON() ([]byte, error)

MarshalJSON renders a sanitized form, safe to log.

func (*ConfigurationError) Origin

func (e *ConfigurationError) Origin() ErrorOrigin

type Envelope

type Envelope struct {
	Code    *int    `json:"code"`
	Message *string `json:"message"`
	// Errors are the item-level failures, normalized to a list. They appear on
	// successful responses too: a bulk request where some EINs were not found
	// is an HTTP 200 with entries here.
	Errors []APIErrorDetail `json:"errors"`
	// TimeTaken is the server-side processing time, in milliseconds.
	TimeTaken *float64 `json:"timeTaken"`
	// NonprofitCheckCount is the checks the account has consumed so far in the
	// current billing cycle, including this request. See Result.CheckCount.
	NonprofitCheckCount *int64 `json:"nonprofit_check_count"`

	// Fields is every field of the response body, exactly as sent.
	Fields Object `json:"-"`
}

Envelope is the wrapper every nonprofit check response arrives in. The payload itself — data — is read into the result, and stays reachable through Fields.

func (Envelope) MarshalJSON

func (e Envelope) MarshalJSON() ([]byte, error)

MarshalJSON returns the response body as it was received.

func (*Envelope) UnmarshalJSON

func (e *Envelope) UnmarshalJSON(data []byte) error

UnmarshalJSON reads a response body, keeping every field in Fields.

type Environment

type Environment string

Environment names a Pactman deployment.

Endpoint hosts are declared in this file and nowhere else. Nothing else in this package contains a literal Pactman host.

const EnvironmentProduction Environment = "production"

EnvironmentProduction is the Pactman production API, and the default.

func SupportedEnvironments

func SupportedEnvironments() []Environment

SupportedEnvironments returns every environment name the SDK understands.

type Error

type Error interface {
	error
	Category() ErrorCategory
	Origin() ErrorOrigin
}

Error is implemented by every error this SDK returns. Use errors.As to reach it through any wrapping:

var perr pactman.Error
if errors.As(err, &perr) { log.Println(perr.Category(), perr.Origin()) }

No Error carries the API key in its message, its fields, or its JSON form.

type ErrorCategory

type ErrorCategory string

ErrorCategory is a stable, machine-comparable error category. Branch on it, on the error's type, or on the Err* sentinels with errors.Is — never on message text.

const (
	// CategoryConfiguration: the client was given unusable options.
	CategoryConfiguration ErrorCategory = "configuration"
	// CategoryValidation: input failed local validation; no request was sent.
	CategoryValidation ErrorCategory = "validation"
	// CategoryAuthentication: HTTP 401. The key is missing, malformed, revoked or unrecognized.
	CategoryAuthentication ErrorCategory = "authentication"
	// CategoryAuthorization: HTTP 403. The key is valid but lacks access.
	CategoryAuthorization ErrorCategory = "authorization"
	// CategoryBadRequest: HTTP 400. The API rejected the request.
	CategoryBadRequest ErrorCategory = "bad_request"
	// CategoryNotFound: HTTP 404. No matching record.
	CategoryNotFound ErrorCategory = "not_found"
	// CategoryRateLimit: HTTP 429. Rate limit exceeded.
	CategoryRateLimit ErrorCategory = "rate_limit"
	// CategoryServer: HTTP 5xx.
	CategoryServer ErrorCategory = "server"
	// CategoryTimeout: an attempt exceeded the configured timeout.
	CategoryTimeout ErrorCategory = "timeout"
	// CategoryNetwork: no HTTP response was produced, or the caller cancelled.
	CategoryNetwork ErrorCategory = "network"
	// CategoryAPI: an API error that fits no more specific category.
	CategoryAPI ErrorCategory = "api"
)

Error categories. Every error this SDK returns carries exactly one.

type ErrorOrigin

type ErrorOrigin string

ErrorOrigin says whether an error was raised locally or derived from an API response.

const (
	OriginLocal ErrorOrigin = "local"
	OriginAPI   ErrorOrigin = "api"
)

Error origins.

type HTTPDoer

type HTTPDoer interface {
	Do(*http.Request) (*http.Response, error)
}

HTTPDoer sends HTTP requests. *http.Client satisfies it; so does any wrapper that counts, logs or proxies requests.

type NetworkError

type NetworkError struct {
	// Attempts is how many attempts were made; 0 when the context had already
	// ended before the first one.
	Attempts int
	// contains filtered or unexported fields
}

NetworkError reports a request that produced no HTTP response, or one the caller cancelled. When the caller's context ended, Unwrap returns its error, so errors.Is(err, context.Canceled) and context.DeadlineExceeded work.

func (*NetworkError) Category

func (e *NetworkError) Category() ErrorCategory

func (*NetworkError) Error

func (e *NetworkError) Error() string

func (*NetworkError) Is

func (e *NetworkError) Is(target error) bool

func (*NetworkError) MarshalJSON

func (e *NetworkError) MarshalJSON() ([]byte, error)

MarshalJSON renders a sanitized form, safe to log.

func (*NetworkError) Origin

func (e *NetworkError) Origin() ErrorOrigin

func (*NetworkError) Unwrap

func (e *NetworkError) Unwrap() error

type Nonprofit

type Nonprofit struct {
	// PactmanOrgURL is the organization's public Pactman profile URL.
	PactmanOrgURL                *string `json:"pactman_org_url"`
	OrganizationInfoLastModified *string `json:"organization_info_last_modified"`

	EIN                 *string `json:"ein"`
	OrganizationName    *string `json:"organization_name"`
	OrganizationNameAKA *string `json:"organization_name_aka"`
	AddressLine1        *string `json:"address_line1"`
	AddressLine2        *string `json:"address_line2"`
	City                *string `json:"city"`
	State               *string `json:"state"`
	StateName           *string `json:"state_name"`
	ZIP                 *string `json:"zip"`
	FilingReqCode       *string `json:"filing_req_code"`

	// IRS Publication 78.
	Pub78ChurchMessage    *string `json:"pub78_church_message"`
	Pub78OrganizationName *string `json:"pub78_organization_name"`
	Pub78EIN              *string `json:"pub78_ein"`
	Pub78Verified         *bool   `json:"pub78_verified"`
	Pub78City             *string `json:"pub78_city"`
	Pub78State            *string `json:"pub78_state"`
	Pub78Indicator        *string `json:"pub78_indicator"`
	// OrganizationTypes are the deductibility entries. An entry can itself be
	// nil, so read through it rather than into it.
	OrganizationTypes []*OrganizationType `json:"organization_types"`
	MostRecentPub78   *string             `json:"most_recent_pub78"`

	// IRS Business Master File.
	BMFChurchMessage          *string `json:"bmf_church_message"`
	BMFOrganizationName       *string `json:"bmf_organization_name"`
	BMFEIN                    *string `json:"bmf_ein"`
	BMFStatus                 *bool   `json:"bmf_status"`
	BMFSubsection             *string `json:"bmf_subsection"`
	MostRecentBMF             *string `json:"most_recent_bmf"`
	SubsectionDescription     *string `json:"subsection_description"`
	FoundationCode            *string `json:"foundation_code"`
	FoundationCodeDescription *string `json:"foundation_code_description"`
	FoundationTypeCode        *string `json:"foundation_type_code"`
	FoundationTypeDescription *string `json:"foundation_type_description"`
	Foundation509aStatus      *string `json:"foundation_509a_status"`
	RulingMonth               *string `json:"ruling_month"`
	RulingYear                *string `json:"ruling_year"`
	GroupExemption            *string `json:"group_exemption"`
	ExemptStatusCode          *string `json:"exempt_status_code"`

	// OFACStatus is the OFAC Specially Designated Nationals finding. The API
	// returns a sentence, not a flag — do not pattern-match it to derive a
	// boolean. Read it, or present it to a reviewer.
	OFACStatus *string `json:"ofac_status"`

	// IRS Automatic Revocation of Exemption.
	RevocationCode    *string `json:"revocation_code"`
	RevocationDate    *string `json:"revocation_date"`
	ReinstatementDate *string `json:"reinstatement_date"`

	// IRSBMFPub78Conflict is true when the IRS BMF and Publication 78 records disagree.
	IRSBMFPub78Conflict *bool   `json:"irs_bmf_pub78_conflict"`
	ReportDate          *string `json:"report_date"`

	// Fields is every field the API returned for this record, exactly as sent,
	// including null ones and ones this SDK does not declare.
	Fields Object `json:"-"`
}

Nonprofit is a nonprofit record as returned by the US nonprofit check endpoints.

Source-specific findings are flat on the record, prefixed by source (Pub78*, BMF*, OFAC*, and the revocation fields for the IRS Automatic Revocation of Exemption list). Pub78, BMF, AROE and OFAC return grouped views.

Every field is optional: the API omits fields it has no data for. A nil field means the API returned no value — either no field, or null. Fields tells those two apart, and holds any field a newer API version returns that this SDK does not declare.

Declared here is what the production API returns. Some deployments serve additional source fields — the BMF address (bmf_city, bmf_state, bmf_street_address), bmf_source_pf_filing_req_cd, bmf_deductability_text, pub78_source_org_type_1..3, ofac_list_published_date and aroe_list_published_date. They are not declared because production does not return them; when it does they are readable through Fields, and this package will declare them in a release of its own.

Nonprofit is a read view of a response. It marshals back to JSON as the fields the API sent, exactly; a Nonprofit built in code, with no Fields, marshals its non-nil declared fields.

func (*Nonprofit) AROE

func (n *Nonprofit) AROE() *AROESource

AROE returns the Automatic Revocation of Exemption findings, or nil if the API returned none.

func (*Nonprofit) BMF

func (n *Nonprofit) BMF() *BMFSource

BMF returns the Business Master File findings, or nil if the API returned none.

func (Nonprofit) MarshalJSON

func (n Nonprofit) MarshalJSON() ([]byte, error)

MarshalJSON returns the record as the API sent it.

func (*Nonprofit) OFAC

func (n *Nonprofit) OFAC() *OFACSource

OFAC returns the OFAC findings, or nil if the API returned none.

func (*Nonprofit) Pub78

func (n *Nonprofit) Pub78() *Pub78Source

Pub78 returns the Publication 78 findings, or nil if the API returned none.

func (*Nonprofit) UnmarshalJSON

func (n *Nonprofit) UnmarshalJSON(data []byte) error

UnmarshalJSON reads a record, keeping every field in Fields.

type NonprofitsResource

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

NonprofitsResource holds the nonprofit lookups. Reach it through Client.Nonprofits.

func (*NonprofitsResource) Check

Check looks up a single nonprofit by EIN.

The EIN is normalized and validated locally first; a malformed EIN returns a *ValidationError without sending a request. When ctx ends, the in-flight attempt and every planned retry stop.

result, err := client.Nonprofits.Check(ctx, "41-1787097")

func (*NonprofitsResource) CheckBulk

func (r *NonprofitsResource) CheckBulk(ctx context.Context, eins []string, opts ...RequestOption) (*BulkCheckResult, error)

CheckBulk looks up to MaxBulkEINs nonprofits in one request.

Every EIN is normalized and validated before anything is sent; if any one fails, the call returns a *ValidationError identifying each offending index, and no request is made. EINs are sent in the order supplied and duplicates are kept unless WithDedupe is passed — but the API matches by set membership, so the response is not ordered to match and a repeated EIN comes back once. Index Organizations by EIN rather than pairing positionally.

EINs the API has no record for are not an error: they arrive on an HTTP 200 in NotFoundEINs. Larger inputs are rejected rather than split; this SDK never turns one call into several billable requests.

func (*NonprofitsResource) Format

func (r *NonprofitsResource) Format(f fmt.State, _ rune)

Format keeps every fmt verb free of the API key.

func (*NonprofitsResource) String

func (r *NonprofitsResource) String() string

String identifies the resource without its credentials.

type OFACSource

type OFACSource struct {
	// Status is the finding as the API phrases it. It is prose, not a flag;
	// the API does not return a boolean match indicator, and this SDK does not
	// invent one by matching on the wording.
	Status *string
}

OFACSource holds the OFAC Specially Designated Nationals findings.

type Object

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

Object is the set of fields the API returned for one JSON object, exactly as it sent them and in the order it sent them.

It is the seam that keeps this SDK forward compatible. A field a newer API version adds is not declared on the typed models, but it is here, readable without a decoding failure or an SDK upgrade. It is also the only place that can tell "the API returned this field as null" apart from "the API did not return this field": the typed models read both as nil, and Has does not.

An Object is immutable. Its zero value holds no fields.

func (Object) Get

func (o Object) Get(name string) (json.RawMessage, bool)

Get returns the field's value as raw JSON, and whether the API returned it. Decode the value with json.Unmarshal into whatever type you expect.

func (Object) Has

func (o Object) Has(name string) bool

Has reports whether the API returned the field, including when it returned it as null.

func (Object) IsNull

func (o Object) IsNull(name string) bool

IsNull reports whether the API returned the field as JSON null. An absent field is not null.

func (Object) Len

func (o Object) Len() int

Len returns how many fields the API returned.

func (Object) MarshalJSON

func (o Object) MarshalJSON() ([]byte, error)

MarshalJSON returns the object exactly as it was received. The zero Object marshals as null.

func (Object) Names

func (o Object) Names() []string

Names returns the field names the API returned, in the order it returned them.

func (*Object) UnmarshalJSON

func (o *Object) UnmarshalJSON(data []byte) error

UnmarshalJSON reads a JSON object. JSON null leaves the Object empty; any other non-object value is an error.

type Option

type Option interface {
	ClientOption
	RequestOption
}

Option is accepted both by NewClient and by each call, where it overrides the client's setting for that call only.

func WithHeader

func WithHeader(name, value string) Option

WithHeader adds a header: to every request when given to NewClient, or to one call. It cannot override Authorization, Accept, User-Agent or Content-Type.

func WithMaxRetries

func WithMaxRetries(retries int) Option

WithMaxRetries changes only the number of retries after the first attempt, keeping the rest of the policy. 0 disables retrying.

func WithRetryPolicy

func WithRetryPolicy(policy RetryPolicy) Option

WithRetryPolicy replaces the retry policy.

func WithTimeout

func WithTimeout(timeout time.Duration) Option

WithTimeout sets the per-attempt timeout. It must be greater than zero.

func WithoutRetries

func WithoutRetries() Option

WithoutRetries disables retrying: every call makes exactly one attempt.

type OrganizationType

type OrganizationType struct {
	OrganizationType               *string `json:"organization_type"`
	DeductibilityLimitation        *string `json:"deductibility_limitation"`
	DeductibilityStatusDescription *string `json:"deductibility_status_description"`

	// Fields is every field the API returned for this entry, exactly as sent.
	Fields Object `json:"-"`
}

OrganizationType is one deductibility entry from IRS Publication 78.

func (OrganizationType) MarshalJSON

func (o OrganizationType) MarshalJSON() ([]byte, error)

MarshalJSON returns the entry as the API sent it.

func (*OrganizationType) UnmarshalJSON

func (o *OrganizationType) UnmarshalJSON(data []byte) error

UnmarshalJSON reads an entry, keeping every field in Fields.

type Pub78Source

type Pub78Source struct {
	Verified          *bool
	OrganizationName  *string
	EIN               *string
	City              *string
	State             *string
	Indicator         *string
	ChurchMessage     *string
	OrganizationTypes []*OrganizationType
	MostRecent        *string
}

Pub78Source holds the IRS Publication 78 findings.

type RequestOption

type RequestOption interface {
	// contains filtered or unexported methods
}

RequestOption overrides the client's settings for one call.

func WithDedupe

func WithDedupe() RequestOption

WithDedupe removes duplicate EINs from a CheckBulk call before it is sent, keeping first-seen order. Duplicates are collapsed after normalization and before the batch limit is applied.

Off by default: duplicates are sent exactly as supplied, because each one consumes quota and silently dropping them would misreport what was checked. On Check, which sends one EIN, it has nothing to do.

type Result

type Result struct {
	// CheckCount is nonprofit_check_count from the envelope: the checks
	// consumed so far in the current billing cycle, including this request,
	// resetting each cycle. It is not the size of this request; take the
	// difference between two responses for that. Nil when not reported.
	CheckCount *int64
	// TimeTaken is the server-side processing time, when reported.
	TimeTaken *time.Duration
	// Errors are item-level failures reported alongside a successful response.
	// Empty when the API reported none.
	Errors []APIErrorDetail
	// RequestID is the correlation identifier from the response headers, when
	// the server sent one.
	RequestID string
	// Status is the HTTP status of the response.
	Status int
	// Raw is the response body, unmodified, including fields not typed here.
	// json.Marshal(result.Raw) returns the body exactly as received.
	Raw Envelope
}

Result holds the fields every result this SDK returns shares.

type RetryPolicy

type RetryPolicy struct {
	// MaxRetries is the retries after the first attempt. 0 disables retrying.
	MaxRetries int
	// InitialDelay is the delay before the first retry. Later delays grow by
	// BackoffFactor and are randomized when Jitter is on.
	InitialDelay time.Duration
	// MaxDelay caps a single backoff delay. A server-supplied Retry-After is
	// honored even when it exceeds this.
	MaxDelay time.Duration
	// BackoffFactor multiplies each successive delay. It must be 1 or more.
	BackoffFactor float64
	// Jitter randomizes each delay across [0, computed] (full jitter), so that
	// clients failing together do not retry in lockstep.
	Jitter bool
	// RetryableStatuses are the HTTP statuses worth retrying. 400, 401, 403 and
	// 404 are never retried, whatever this contains.
	RetryableStatuses []int
	// RespectRetryAfter waits for the server's Retry-After before falling back
	// to backoff.
	RespectRetryAfter bool
}

RetryPolicy controls automatic retries. Start from DefaultRetryPolicy, or from Client.RetryPolicy, and change what you need.

func DefaultRetryPolicy

func DefaultRetryPolicy() RetryPolicy

DefaultRetryPolicy returns the policy a client uses unless told otherwise: two retries (three attempts), exponential backoff from 500ms with full jitter, capped at 8s per delay, on 429, 500, 502, 503 and 504, honoring Retry-After.

type SingleCheckResult

type SingleCheckResult struct {
	Result
	// Nonprofit is the organization, or nil when the API returned no record.
	Nonprofit *Nonprofit
}

SingleCheckResult is the result of NonprofitsResource.Check.

type TimeoutError

type TimeoutError struct {
	// Timeout is the per-attempt timeout that expired.
	Timeout time.Duration
	// Attempts is how many attempts were made.
	Attempts int
}

TimeoutError reports an attempt that exceeded the configured per-attempt timeout.

The caller's own context ending is a *NetworkError, not this, and a TimeoutError deliberately does not match context.DeadlineExceeded: the two mean different things — raise the budget or shed load, versus the caller went away — and conflating them hides which side gave up.

func (*TimeoutError) Category

func (e *TimeoutError) Category() ErrorCategory

func (*TimeoutError) Error

func (e *TimeoutError) Error() string

func (*TimeoutError) Is

func (e *TimeoutError) Is(target error) bool

func (*TimeoutError) MarshalJSON

func (e *TimeoutError) MarshalJSON() ([]byte, error)

MarshalJSON renders a sanitized form, safe to log.

func (*TimeoutError) Origin

func (e *TimeoutError) Origin() ErrorOrigin

type ValidationError

type ValidationError struct {

	// Issues lists every rejected item. A bulk call reports all of them at once.
	Issues []ValidationIssue
	// contains filtered or unexported fields
}

ValidationError reports input that failed local validation. No HTTP request was sent. Its origin is OriginLocal, which is what separates it from an API-side 400.

func (*ValidationError) Category

func (e *ValidationError) Category() ErrorCategory

func (*ValidationError) Error

func (e *ValidationError) Error() string

func (*ValidationError) Is

func (e *ValidationError) Is(target error) bool

func (*ValidationError) MarshalJSON

func (e *ValidationError) MarshalJSON() ([]byte, error)

MarshalJSON renders a sanitized form, safe to log.

func (*ValidationError) Origin

func (e *ValidationError) Origin() ErrorOrigin

type ValidationIssue

type ValidationIssue struct {
	// Message says why the value was rejected.
	Message string `json:"message"`
	// Index is the item's position in the input list, or -1 when the value was
	// not part of a list.
	Index int `json:"index"`
	// Value is the offending value, as supplied.
	Value string `json:"value"`
}

ValidationIssue is one item that failed local validation.

Jump to

Keyboard shortcuts

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