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
- Variables
- func BaseURLForEnvironment(environment Environment) (string, error)
- func IsValidEIN(input string) bool
- func NormalizeEIN(input string) (string, error)
- func NormalizeEINs(inputs []string) ([]string, error)
- type APIError
- type APIErrorDetail
- type AROESource
- type BMFSource
- type BulkCheckResult
- type Client
- func (c *Client) BaseURL() string
- func (c *Client) Environment() Environment
- func (c *Client) Format(f fmt.State, _ rune)
- func (c *Client) GoString() string
- func (c *Client) LogValue() slog.Value
- func (c *Client) MarshalJSON() ([]byte, error)
- func (c *Client) RetryPolicy() RetryPolicy
- func (c *Client) String() string
- func (c *Client) Timeout() time.Duration
- type ClientOption
- type ConfigurationError
- type Envelope
- type Environment
- type Error
- type ErrorCategory
- type ErrorOrigin
- type HTTPDoer
- type NetworkError
- type Nonprofit
- type NonprofitsResource
- func (r *NonprofitsResource) Check(ctx context.Context, ein string, opts ...RequestOption) (*SingleCheckResult, error)
- func (r *NonprofitsResource) CheckBulk(ctx context.Context, eins []string, opts ...RequestOption) (*BulkCheckResult, error)
- func (r *NonprofitsResource) Format(f fmt.State, _ rune)
- func (r *NonprofitsResource) String() string
- type OFACSource
- type Object
- type Option
- type OrganizationType
- type Pub78Source
- type RequestOption
- type Result
- type RetryPolicy
- type SingleCheckResult
- type TimeoutError
- type ValidationError
- type ValidationIssue
Constants ¶
const BulkCheckPath = "/api/entities/nonprofitcheckbulk/v1/us/eins"
BulkCheckPath is the path of the bulk-check endpoint.
const DefaultEnvironment = EnvironmentProduction
DefaultEnvironment is the environment used when none is configured.
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.
const EINLength = 9
EINLength is the number of digits in an EIN.
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.
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.
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.
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 ¶
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 ¶
IsValidEIN reports whether input is shaped like an EIN.
func NormalizeEIN ¶
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 ¶
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) MarshalJSON ¶
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 ¶
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) Environment ¶
func (c *Client) Environment() Environment
Environment returns the named environment in use, or "" when WithBaseURL gave an explicit host.
func (*Client) MarshalJSON ¶
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.
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 ¶
MarshalJSON returns the response body as it was received.
func (*Envelope) UnmarshalJSON ¶
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 ¶
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 ¶
BMF returns the Business Master File findings, or nil if the API returned none.
func (Nonprofit) MarshalJSON ¶
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 ¶
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 ¶
func (r *NonprofitsResource) Check(ctx context.Context, ein string, opts ...RequestOption) (*SingleCheckResult, error)
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 ¶
Has reports whether the API returned the field, including when it returned it as null.
func (Object) IsNull ¶
IsNull reports whether the API returned the field as JSON null. An absent field is not null.
func (Object) MarshalJSON ¶
MarshalJSON returns the object exactly as it was received. The zero Object marshals as null.
func (Object) Names ¶
Names returns the field names the API returned, in the order it returned them.
func (*Object) UnmarshalJSON ¶
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 ¶
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 ¶
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 ¶
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.