Documentation
¶
Index ¶
- Constants
- func Bool(v bool) *bool
- func BuildQRURL(baseURL, code string, options *QROptions) string
- func Int(v int) *int
- func Int64(v int64) *int64
- func String(v string) *string
- func VerifySignature(rawBody, signatureHeader, secret string, opts ...SignatureOption) bool
- type ABVariant
- type BatchCreateLinksResult
- type BatchLinkInput
- type BatchLinkResult
- type Client
- type ConversionResult
- type Conversions
- type CreateABVariantInput
- type CreateLinkInput
- type CreateTagInput
- type CreateWebhookInput
- type CreatedWebhook
- type DailyClicksPoint
- type DeleteResult
- type Environment
- type Link
- type LinkStats
- type Links
- func (l *Links) Create(ctx context.Context, input CreateLinkInput) (*Link, error)
- func (l *Links) CreateBatch(ctx context.Context, links []BatchLinkInput) (*BatchCreateLinksResult, error)
- func (l *Links) Delete(ctx context.Context, code string) (*DeleteResult, error)
- func (l *Links) Get(ctx context.Context, code string) (*Link, error)
- func (l *Links) List(ctx context.Context, params *ListLinksParams) (*ListLinksResult, error)
- func (l *Links) Stats(ctx context.Context, code string, days int) (*LinkStats, error)
- func (l *Links) Update(ctx context.Context, code string, input UpdateLinkInput) (*Link, error)
- type ListLinksParams
- type ListLinksResult
- type ListTagsResult
- type ListWebhooksResult
- type Option
- type Project
- type ProjectNS
- type ProjectStats
- type QR
- type QROptions
- type RecordConversionInput
- type ReroutError
- type RoutingRule
- type SignatureOption
- type StatsBreakdown
- type Tag
- type TagSummary
- type Tags
- func (t *Tags) Create(ctx context.Context, input CreateTagInput) (*Tag, error)
- func (t *Tags) Delete(ctx context.Context, tagID string) (*DeleteResult, error)
- func (t *Tags) List(ctx context.Context) (*ListTagsResult, error)
- func (t *Tags) Update(ctx context.Context, tagID string, input UpdateTagInput) (*Tag, error)
- type UpdateLinkInput
- type UpdateTagInput
- type Webhook
- type Webhooks
Constants ¶
const ( CodeForbidden = "forbidden" CodeNotFound = "not_found" CodeRateLimited = "rate_limited" CodeServerError = "server_error" CodeClientError = "client_error" CodeNetworkError = "network_error" CodeTimeout = "timeout" CodeUnexpectedResponse = "unexpected_response" CodeMissingAPIKey = "missing_api_key" CodeBadRequest = "bad_request" )
Synthetic Code values, used when the server didn't return a JSON error body or the request never reached the server.
const DefaultBaseURL = "https://api.rerout.co"
DefaultBaseURL is the production Rerout API endpoint. Override via WithBaseURL for staging or self-hosted deployments.
const DefaultSignatureToleranceSeconds = 300
DefaultSignatureToleranceSeconds is the default window (in seconds) between the `t=` timestamp on the signature and the current time. Five minutes — matches the TS / Dart reference SDKs.
const DefaultTimeout = 30 * time.Second
DefaultTimeout is the per-request HTTP timeout applied when no http.Client is injected and WithTimeout is not used.
const SandboxBaseURL = "https://sandbox-api.rerout.co"
Variables ¶
This section is empty.
Functions ¶
func BuildQRURL ¶
BuildQRURL is the standalone version of QR.URL. Useful when you have a base URL handy but not a full Client (e.g. server-side template helpers).
Trailing slashes on baseURL are stripped; the code is path-escaped.
func String ¶
String returns a pointer to v. Use in struct literals where an optional *string is required.
func VerifySignature ¶
func VerifySignature(rawBody, signatureHeader, secret string, opts ...SignatureOption) bool
VerifySignature verifies an X-Rerout-Signature header against rawBody using the endpoint signing secret. Returns true only when the timestamp is within the tolerance and the HMAC matches in constant time.
Returns false when:
- signatureHeader or secret is empty,
- the header is malformed (missing `t=` or `v1=`, non-numeric or non- positive `t`, non-hex or odd-length `v1`),
- the timestamp is outside the tolerance window (skipped when tolerance is 0),
- the computed HMAC doesn't match the supplied v1.
Key matching is case-insensitive (`T=` / `V1=` accepted), the hex digest is decoded case-insensitively, and the byte-level comparison is constant time (hmac.Equal).
ok := rerout.VerifySignature(
rawBody,
r.Header.Get("X-Rerout-Signature"),
os.Getenv("REROUT_WEBHOOK_SECRET"),
)
if !ok {
w.WriteHeader(http.StatusBadRequest)
return
}
Types ¶
type ABVariant ¶ added in v0.5.0
type ABVariant struct {
ID int64 `json:"id"`
TargetURL string `json:"target_url"`
Weight int `json:"weight"`
}
ABVariant is one weighted Smart-Links A/B testing destination. Inbound traffic is split across variants in proportion to their Weight.
ID is server-assigned and read-only on responses. On CreateABVariantInput it is absent.
type BatchCreateLinksResult ¶ added in v0.5.0
type BatchCreateLinksResult struct {
Created int `json:"created"`
Total int `json:"total"`
Results []BatchLinkResult `json:"results"`
}
BatchCreateLinksResult is the response from POST /v1/links/batch.
type BatchLinkInput ¶ added in v0.5.0
type BatchLinkInput struct {
TargetURL string `json:"target_url"`
Code *string `json:"code,omitempty"`
ExpiresAt *int64 `json:"expires_at,omitempty"`
DomainHostname *string `json:"domain_hostname,omitempty"`
}
BatchLinkInput is one entry in a CreateLinks batch. TargetURL is required; the rest are optional pointers omitted when unset.
type BatchLinkResult ¶ added in v0.5.0
type BatchLinkResult struct {
Index int `json:"index"`
OK bool `json:"ok"`
Code *string `json:"code,omitempty"`
Error *string `json:"error,omitempty"`
}
BatchLinkResult is the per-item outcome of a CreateLinks batch. Index is the zero-based position of the input link. OK reports success; on success Code is populated, otherwise Error carries the failure reason.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is the official Go client for the Rerout API. Construct via NewClient; the zero value is not usable.
Clients are safe for concurrent use by multiple goroutines as long as the underlying http.Client is (the stdlib default is).
func NewClient ¶
NewClient constructs a Client.
apiKey must be non-empty (the constructor returns a *ReroutError with code "missing_api_key" otherwise). All other settings have sensible defaults and can be overridden via Option arguments.
func (*Client) BaseURL ¶
BaseURL returns the resolved base URL — trailing-slash-trimmed. Exposed for diagnostics and the QR URL builder.
func (*Client) Conversions ¶ added in v0.5.0
func (c *Client) Conversions() *Conversions
Conversions returns the conversion-tracking namespace.
type ConversionResult ¶ added in v0.5.0
ConversionResult is the response from POST /v1/conversions.
Duplicate is true when the (click_id, event_name) pair was already recorded — the call is idempotent, so Recorded reflects whether a new row was written.
type Conversions ¶ added in v0.5.0
type Conversions struct {
// contains filtered or unexported fields
}
Conversions is the conversion-tracking namespace. Construct via Client.Conversions().
func (*Conversions) Record ¶ added in v0.5.0
func (c *Conversions) Record(ctx context.Context, input RecordConversionInput) (*ConversionResult, error)
Record records a conversion event against a click via POST /v1/conversions.
ClickID and EventName are required on input. The call is idempotent on the (click_id, event_name) pair: the returned ConversionResult reports whether a new row was Recorded and whether the event was a Duplicate of one already stored.
type CreateABVariantInput ¶ added in v0.5.0
type CreateABVariantInput struct {
TargetURL string `json:"target_url"`
Weight *int `json:"weight,omitempty"`
}
CreateABVariantInput is one weighted A/B variant on CreateLinkInput / UpdateLinkInput. Weight is optional — the server applies an even split when it is unset.
type CreateLinkInput ¶
type CreateLinkInput struct {
TargetURL string `json:"target_url"`
DomainHostname *string `json:"domain_hostname,omitempty"`
Code *string `json:"code,omitempty"`
ExpiresAt *int64 `json:"expires_at,omitempty"`
SEOTitle *string `json:"seo_title,omitempty"`
SEODescription *string `json:"seo_description,omitempty"`
SEOImageURL *string `json:"seo_image_url,omitempty"`
SEOCanonicalURL *string `json:"seo_canonical_url,omitempty"`
SEONoindex *bool `json:"seo_noindex,omitempty"`
// Password, when set, requires visitors to enter it before redirecting.
Password *string `json:"password,omitempty"`
// MaxClicks caps the number of redirects. Omit for an uncapped link.
MaxClicks *int64 `json:"max_clicks,omitempty"`
// TrackConversions enables conversion tracking for the link.
TrackConversions *bool `json:"track_conversions,omitempty"`
// RoutingRules are conditional redirect rules, evaluated in order.
RoutingRules []RoutingRule `json:"routing_rules,omitempty"`
// ABVariants are weighted A/B testing destinations.
ABVariants []CreateABVariantInput `json:"ab_variants,omitempty"`
}
CreateLinkInput is the body for POST /v1/links.
Optional fields are pointers so the JSON encoder omits unset ones. Use the String / Int64 / Bool helpers for clear call sites:
in := rerout.CreateLinkInput{
TargetURL: "https://example.com/q4",
DomainHostname: rerout.String("go.brand.com"),
Code: rerout.String("q4"),
SEONoindex: rerout.Bool(false),
}
type CreateTagInput ¶ added in v0.5.0
CreateTagInput is the body for POST /v1/projects/me/tags.
Name is required. Color is optional — pointer so the JSON encoder omits it when unset, letting the server validate against its palette and default to "teal".
in := rerout.CreateTagInput{
Name: "Spring 2026",
Color: rerout.String("teal"),
}
type CreateWebhookInput ¶ added in v0.3.0
type CreateWebhookInput struct {
Name string `json:"name"`
URL string `json:"url"`
Events []string `json:"events"`
IsActive *bool `json:"is_active,omitempty"`
PayloadFormat *string `json:"payload_format,omitempty"`
}
CreateWebhookInput is the body for POST /v1/projects/me/webhooks.
Name, URL, and Events are required. Optional fields are pointers so the JSON encoder omits unset ones — letting the server apply its defaults (IsActive defaults to true; PayloadFormat defaults to "json").
in := rerout.CreateWebhookInput{
Name: "Order events",
URL: "https://example.com/hooks/rerout",
Events: []string{"link.created", "link.clicked"},
IsActive: rerout.Bool(true),
PayloadFormat: rerout.String("json"),
}
type CreatedWebhook ¶ added in v0.3.0
type CreatedWebhook struct {
Endpoint Webhook `json:"endpoint"`
SigningSecret string `json:"signing_secret"`
}
CreatedWebhook is the response from POST /v1/projects/me/webhooks.
SigningSecret (a "whsec_…" value) is returned ONCE — persist it now so you can verify deliveries with VerifySignature; it is never shown again.
type DailyClicksPoint ¶
type DailyClicksPoint struct {
Day int64 `json:"day"`
Clicks int64 `json:"clicks"`
QRScans int64 `json:"qr_scans"`
}
DailyClicksPoint is one point in a daily-clicks time series.
type DeleteResult ¶
type DeleteResult struct {
Deleted bool `json:"deleted"`
}
DeleteResult is the response body from DELETE /v1/links/:code and DELETE /v1/projects/me/webhooks/:id.
type Environment ¶ added in v0.6.0
type Environment string
const ( EnvironmentProduction Environment = "production" EnvironmentSandbox Environment = "sandbox" )
type Link ¶
type Link struct {
Code string `json:"code"`
ShortURL string `json:"short_url"`
DomainHostname *string `json:"domain_hostname,omitempty"`
TargetURL string `json:"target_url"`
ProjectID string `json:"project_id"`
ExpiresAt *int64 `json:"expires_at,omitempty"`
IsActive bool `json:"is_active"`
SEOTitle *string `json:"seo_title,omitempty"`
SEODescription *string `json:"seo_description,omitempty"`
SEOImageURL *string `json:"seo_image_url,omitempty"`
SEOCanonicalURL *string `json:"seo_canonical_url,omitempty"`
SEONoindex bool `json:"seo_noindex"`
SEOUpdatedAt *int64 `json:"seo_updated_at,omitempty"`
Tags []Tag `json:"tags"`
// PasswordProtected reports whether the link requires a password before it
// redirects. The password itself is never returned.
PasswordProtected bool `json:"password_protected"`
// MaxClicks is the click cap after which the link stops redirecting. Nil
// for an uncapped link.
MaxClicks *int64 `json:"max_clicks,omitempty"`
// ClickCount is the number of clicks recorded against the link so far.
ClickCount int64 `json:"click_count"`
// TrackConversions reports whether conversion tracking is enabled.
TrackConversions bool `json:"track_conversions"`
// RoutingRules are the conditional redirect rules, evaluated in order.
RoutingRules []RoutingRule `json:"routing_rules"`
// ABVariants are the weighted A/B testing destinations.
ABVariants []ABVariant `json:"ab_variants"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
Link is the canonical short-link representation returned by the API.
type LinkStats ¶
type LinkStats struct {
Code string `json:"code"`
Days int `json:"days"`
TotalClicks int64 `json:"total_clicks"`
QRScans int64 `json:"qr_scans"`
Countries []StatsBreakdown `json:"countries"`
Referrers []StatsBreakdown `json:"referrers"`
}
LinkStats is the response from GET /v1/links/:code/stats.
type Links ¶
type Links struct {
// contains filtered or unexported fields
}
Links is the link-operations namespace. Construct via Client.Links().
func (*Links) CreateBatch ¶ added in v0.5.0
func (l *Links) CreateBatch(ctx context.Context, links []BatchLinkInput) (*BatchCreateLinksResult, error)
CreateBatch creates multiple links in a single request via POST /v1/links/batch. The returned BatchCreateLinksResult reports the per-item outcome: each result carries its input Index, an OK flag, and either the new Code (on success) or an Error string (on failure). A partial success is possible — Created may be less than Total.
An empty input slice is a client-side error and never hits the API.
func (*Links) Delete ¶
Delete soft-deletes a link. The short URL stops redirecting and disappears from list results.
func (*Links) List ¶
func (l *Links) List(ctx context.Context, params *ListLinksParams) (*ListLinksResult, error)
List returns a paginated page of links. Pass nil for default cursor / limit.
func (*Links) Stats ¶
Stats returns per-link click stats. The window defaults to 30 days when days <= 0.
type ListLinksParams ¶
type ListLinksParams struct {
// Cursor is the pagination cursor returned by a previous List call.
Cursor *int64
// Limit is the page size. Server-side default and max apply.
Limit *int
}
ListLinksParams are the optional cursor / limit query parameters for Links.List.
type ListLinksResult ¶
type ListLinksResult struct {
Links []Link `json:"links"`
NextCursor *int64 `json:"next_cursor,omitempty"`
}
ListLinksResult is one page of links returned by GET /v1/links.
func (ListLinksResult) HasMore ¶
func (r ListLinksResult) HasMore() bool
HasMore reports whether NextCursor is set — i.e. another page is available.
type ListTagsResult ¶ added in v0.5.0
type ListTagsResult struct {
Tags []TagSummary `json:"tags"`
}
ListTagsResult is the response from GET /v1/projects/me/tags.
type ListWebhooksResult ¶ added in v0.3.0
type ListWebhooksResult struct {
Endpoints []Webhook `json:"endpoints"`
// EventTypes lists every event type the server can deliver.
EventTypes []string `json:"event_types"`
}
ListWebhooksResult is the response from GET /v1/projects/me/webhooks.
type Option ¶
type Option func(*clientConfig)
Option configures a Client at construction time. See WithBaseURL, WithHTTPClient, WithTimeout, and WithDefaultHeaders.
func WithBaseURL ¶
WithBaseURL overrides the API base URL. Trailing slashes are stripped. Useful for staging / self-hosted setups.
func WithDefaultHeaders ¶
WithDefaultHeaders sets headers attached to every outgoing request, e.g. "User-Agent" or correlation IDs. The SDK overrides "Authorization", "Accept", and "Content-Type" — those cannot be replaced.
func WithEnvironment ¶ added in v0.6.0
func WithEnvironment(environment Environment) Option
WithEnvironment selects production or the isolated Rerout sandbox.
func WithHTTPClient ¶
WithHTTPClient injects a pre-configured *http.Client. Use this when you need a custom transport (proxy, instrumentation, retries) or when sharing a client with the rest of your application.
If WithHTTPClient is supplied together with WithTimeout, the timeout option is ignored — set the timeout on the injected client instead.
func WithSandbox ¶ added in v0.6.0
func WithSandbox() Option
WithSandbox selects the isolated sandbox environment.
func WithTimeout ¶
WithTimeout sets a per-request timeout. Defaults to DefaultTimeout (30s). Ignored when WithHTTPClient is also supplied.
type ProjectNS ¶
type ProjectNS struct {
// contains filtered or unexported fields
}
ProjectNS is the project-operations namespace. Construct via Client.Project(). The trailing "NS" disambiguates from the Project response type.
type ProjectStats ¶
type ProjectStats struct {
Days int `json:"days"`
TotalClicks int64 `json:"total_clicks"`
QRScans int64 `json:"qr_scans"`
Daily []DailyClicksPoint `json:"daily"`
Countries []StatsBreakdown `json:"countries"`
Referrers []StatsBreakdown `json:"referrers"`
Devices []StatsBreakdown `json:"devices"`
Browsers []StatsBreakdown `json:"browsers"`
TopCodes []StatsBreakdown `json:"top_codes"`
}
ProjectStats is the response from GET /v1/projects/me/stats.
type QR ¶
type QR struct {
// contains filtered or unexported fields
}
QR is the QR-helpers namespace. Construct via Client.QR().
func (*QR) SVG ¶
SVG fetches the rendered QR as an SVG string. Hits the same endpoint as URL but attaches the bearer token and returns the body.
func (*QR) URL ¶
URL builds the URL the Rerout API serves the QR SVG from. Pure — does not call the API. Authentication is the caller's responsibility, since plain <img src=…> tags can't add a bearer token; typically you pass the URL through a server-side proxy.
u := c.QR().URL("q4", nil)
// → https://api.rerout.co/v1/links/q4/qr
branded := c.QR().URL("q4", &rerout.QROptions{
Size: rerout.Int(12),
ECC: "H",
Domain: "go.brand.com",
})
type QROptions ¶
type QROptions struct {
// Size is the module size in pixels. 1-32. Server default: 8.
Size *int
// Margin is the quiet zone in modules. 0-16. Server default: 4.
Margin *int
// ECC is the error-correction level: "L", "M", "Q", or "H".
ECC string
// Domain forces the QR to encode a specific verified custom domain.
Domain string
// Refresh is a cache-bust token. RefreshTrue == true sends "refresh=1";
// otherwise Refresh is forwarded verbatim and triggers a fresh render.
Refresh string
RefreshTrue bool
}
QROptions controls the QR rendering parameters for Client.QR.URL / Client.QR.SVG.
All fields are optional — leave them unset to use the server defaults.
type RecordConversionInput ¶ added in v0.5.0
type RecordConversionInput struct {
ClickID string `json:"click_id"`
EventName string `json:"event_name"`
ValueCents *int64 `json:"value_cents,omitempty"`
Currency *string `json:"currency,omitempty"`
}
RecordConversionInput is the body for POST /v1/conversions.
ClickID and EventName are required. ValueCents and Currency are optional — pointers so they are omitted when unset.
in := rerout.RecordConversionInput{
ClickID: "clk_123",
EventName: "purchase",
ValueCents: rerout.Int64(4999),
Currency: rerout.String("USD"),
}
type ReroutError ¶
type ReroutError struct {
// Code is the stable error code — either from the API response body or a
// synthetic value defined above.
Code string
// Status is the HTTP status code, or 0 when the request never reached the
// server (network failure, timeout, client-side validation).
Status int
// Message is a human-readable description of what went wrong.
Message string
// Path is the API path that produced the error, when known.
Path string
// Timestamp is the server-supplied ISO 8601 timestamp, when present.
Timestamp string
// Details is the parsed JSON error body or any other diagnostic payload.
// Always safe to ignore — Code and Message are the canonical fields.
Details any
// Cause is the wrapped error, when this ReroutError stems from a lower-
// level failure (network error, parse failure). Exposed via Unwrap so
// errors.Is / errors.As reach the underlying error.
Cause error
}
ReroutError is the error type returned by every Client method. It implements the standard error interface, so it works with errors.Is / errors.As.
Callers should branch on Code, not on Message:
var rerr *rerout.ReroutError
if errors.As(err, &rerr) {
switch rerr.Code {
case "bad_target_url":
// ...
}
if rerr.IsRateLimited() {
// back off & retry
}
}
func AsReroutError ¶
func AsReroutError(err error) *ReroutError
AsReroutError extracts the underlying *ReroutError from err, or nil if err is not a ReroutError. This is a small convenience over errors.As — feel free to use errors.As directly.
func (*ReroutError) Error ¶
func (e *ReroutError) Error() string
Error implements the error interface.
func (*ReroutError) IsRateLimited ¶
func (e *ReroutError) IsRateLimited() bool
IsRateLimited reports whether the failure is HTTP 429 — caller should back off and retry.
func (*ReroutError) IsServerError ¶
func (e *ReroutError) IsServerError() bool
IsServerError reports whether the failure is HTTP 5xx — a server-side issue. Generally worth retrying after backoff.
func (*ReroutError) Unwrap ¶
func (e *ReroutError) Unwrap() error
Unwrap returns the wrapped cause, if any, so errors.Is / errors.As reach it.
type RoutingRule ¶ added in v0.5.0
type RoutingRule struct {
ConditionType string `json:"condition_type"`
ConditionOp string `json:"condition_op"`
ConditionValue string `json:"condition_value"`
TargetURL string `json:"target_url"`
}
RoutingRule is one Smart-Links conditional redirect. When the inbound request matches the condition, the link routes to TargetURL instead of the link's default destination.
ConditionType is "country" or "device"; ConditionOp is "is", "is_not", or "in". For the "in" operator, ConditionValue is a comma-separated list.
type SignatureOption ¶
type SignatureOption func(*signatureConfig)
SignatureOption customises VerifySignature.
func WithClock ¶
func WithClock(now func() int64) SignatureOption
WithClock injects a custom clock for deterministic tests. The function returns the current unix time in seconds.
func WithTolerance ¶
func WithTolerance(seconds int) SignatureOption
WithTolerance overrides the timestamp tolerance window in seconds. Pass 0 to disable the timestamp check entirely.
type StatsBreakdown ¶
StatsBreakdown is one bucket in an analytics breakdown — one country, one device class, one referrer, etc.
type Tag ¶ added in v0.2.0
Tag is a label attached to a link. Returned in link responses and as the body of Tags.Create / Tags.Update.
type TagSummary ¶ added in v0.5.0
TagSummary is a Tag plus the number of live (non-deleted) links it is attached to. Returned by Tags.List — the create/update responses use the plain Tag shape and omit LinkCount.
type Tags ¶ added in v0.5.0
type Tags struct {
// contains filtered or unexported fields
}
Tags is the tag-management namespace. Construct via Client.Tags().
func (*Tags) Create ¶ added in v0.5.0
Create creates a tag. Name is required; Color is optional and defaults server-side when omitted. The response omits the link count.
func (*Tags) Delete ¶ added in v0.5.0
Delete removes a tag and drops its assignments from all links. Tag ids look like "tag_…". The response body is {"deleted": true}.
func (*Tags) List ¶ added in v0.5.0
func (t *Tags) List(ctx context.Context) (*ListTagsResult, error)
List returns the project's tags with their live link counts. Each returned TagSummary carries the number of non-deleted links the tag is attached to.
type UpdateLinkInput ¶
type UpdateLinkInput struct {
TargetURL *string `json:"-"`
ExpiresAt *int64 `json:"-"`
ClearExpiresAt bool `json:"-"`
IsActive *bool `json:"-"`
SEOTitle *string `json:"-"`
ClearSEOTitle bool `json:"-"`
SEODescription *string `json:"-"`
ClearSEODescription bool `json:"-"`
SEOImageURL *string `json:"-"`
ClearSEOImageURL bool `json:"-"`
SEOCanonicalURL *string `json:"-"`
ClearSEOCanonicalURL bool `json:"-"`
SEONoindex *bool `json:"-"`
// Password sets a new password; ClearPassword removes password protection
// (sends "password": null). ClearPassword wins over Password.
Password *string `json:"-"`
ClearPassword bool `json:"-"`
// MaxClicks sets a new click cap; ClearMaxClicks removes the cap (sends
// "max_clicks": null). ClearMaxClicks wins over MaxClicks.
MaxClicks *int64 `json:"-"`
ClearMaxClicks bool `json:"-"`
// TrackConversions toggles conversion tracking.
TrackConversions *bool `json:"-"`
// RoutingRules, when non-nil, fully replaces the link's routing rules. A
// non-nil empty slice clears all rules. Nil leaves them untouched.
RoutingRules *[]RoutingRule `json:"-"`
// ABVariants, when non-nil, fully replaces the link's A/B variants. A
// non-nil empty slice clears all variants. Nil leaves them untouched.
ABVariants *[]CreateABVariantInput `json:"-"`
}
UpdateLinkInput is the body for PATCH /v1/links/:code.
Every field is optional. The struct distinguishes "leave the field alone" from "set the field to null on the server" via the ClearXxx flag pattern:
rerout.UpdateLinkInput{
TargetURL: rerout.String("https://example.com/new"),
ClearExpiresAt: true, // sends "expires_at": null
SEOTitle: rerout.String("Black Friday"), // sets the title
ClearSEOImageURL: true, // wipes the image
}
MarshalJSON emits explicit nulls for cleared fields and omits unset ones. An empty payload (no field set, no clear flag) is a client-side error — Client.Links.Update rejects it without hitting the API.
func (UpdateLinkInput) IsEmpty ¶
func (u UpdateLinkInput) IsEmpty() bool
IsEmpty reports whether no field is set and no clear flag is true. Sending an empty PATCH is a client-side error.
func (UpdateLinkInput) MarshalJSON ¶
func (u UpdateLinkInput) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler for UpdateLinkInput.
It walks each field, emitting:
- the value when the field is set,
- an explicit `null` when the matching ClearXxx flag is true,
- nothing when neither — so server-side merge semantics leave the field untouched.
type UpdateTagInput ¶ added in v0.5.0
UpdateTagInput is the body for PATCH /v1/projects/me/tags/:tag_id.
Both fields are optional. A nil field is omitted from the request so the server leaves it unchanged; only fields you set are forwarded. This mirrors Links.Update: an empty payload is a client-side error — Tags.Update rejects it without hitting the API (the server would otherwise return 400).
rerout.UpdateTagInput{Color: rerout.String("red")} // sends {"color":"red"}
func (UpdateTagInput) IsEmpty ¶ added in v0.5.0
func (u UpdateTagInput) IsEmpty() bool
IsEmpty reports whether no field is set. Sending an empty PATCH is a client-side error.
func (UpdateTagInput) MarshalJSON ¶ added in v0.5.0
func (u UpdateTagInput) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler for UpdateTagInput, emitting only the fields that are set so omitted fields are left unchanged server-side.
type Webhook ¶ added in v0.3.0
type Webhook struct {
ID string `json:"id"`
ProjectID string `json:"project_id"`
Name string `json:"name"`
URL string `json:"url"`
Events []string `json:"events"`
IsActive bool `json:"is_active"`
PayloadFormat string `json:"payload_format"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
LastDeliveryAt *int64 `json:"last_delivery_at,omitempty"`
LastSuccessAt *int64 `json:"last_success_at,omitempty"`
LastFailureAt *int64 `json:"last_failure_at,omitempty"`
}
Webhook is a webhook endpoint registered to the project. Mirrors the server-side WebhookEndpointResponse shape.
type Webhooks ¶ added in v0.3.0
type Webhooks struct {
// contains filtered or unexported fields
}
Webhooks is the webhook-endpoint-management namespace. Construct via Client.Webhooks().
func (*Webhooks) Create ¶ added in v0.3.0
func (w *Webhooks) Create(ctx context.Context, input CreateWebhookInput) (*CreatedWebhook, error)
Create registers a webhook endpoint for the project that owns the API key.
The returned CreatedWebhook carries a SigningSecret ("whsec_…") that is shown ONCE — persist it now so you can verify deliveries with VerifySignature; it is never returned again.