Reference
SDK reference
On this page
Types
- Types
- MarketOptions
- ListingInput
- Listing
- DefineOptions
- DefineResult
- Product
- ProductSurface
- ProvisionEvent
- ProvisionResult
- CancelEvent
- MarketEventName
- AffiliateRegisterInput
- AffiliateRegisterResult
- AffiliateProgram
- AffiliateDisableResult
- AffiliateTerm
- AffiliateProgramState
- AffiliateSurface
- VocabularySurface
- VocabularyTerm
- VocabularyCategory
- MarketValidationIssue
- RequestResult
Look up a method's parameters, result, and retry behavior here. For a complete listing exercise, start with the seller quickstart.
This reference describes @metzia/sdk version 0.1.1 on Node.js 20 or later.
The SDK package version is separate from the /api/v1 API version. The API serves
buyers in the United States; prices are in US dollars.
Install the package from npm with
npm install @metzia/sdk, then follow the
seller quickstart. The source is public
at github.com/metziaai/metzia-sdk under
the Apache 2.0 license.
Client setupLink to this section
new Market(key, options)Link to this section
Creates a client for one platform key and one host.
Signature
new Market(key: string | undefined, options?: MarketOptions): MarketParameters
| Name | Type | Required/default | Meaning |
|---|---|---|---|
key | string | Required, nonblank | Your seller API key. The SDK trims surrounding spaces. |
options | MarketOptions | Optional | Host, webhook secret, and vocabulary cache settings. |
Returns: a Market instance. The SDK does not read environment variables.
Pass the key from your application. The key stays in a private field and is not
included when the client is serialized.
Example
Read the key in your application and pass the sandbox host explicitly.
import { Market } from "@metzia/sdk";
const market = new Market(process.env.METZIA_KEY, {
baseUrl: "https://sandbox.metzia.ai",
});Errors: Error for a missing or blank key, an invalid base URL, a URL with a
query or fragment, or an invalid vocabularyTtlMs value.
Retry behavior: not applicable. The constructor does not send a network request.
market.requestLink to this section
Sends one request to a path on this client's host. Use it for API routes that do not have a dedicated SDK method.
Signature
market.request<T>(path: string, init?: RequestInit): Promise<RequestResult<T>>Parameters
| Name | Type | Required/default | Meaning |
|---|---|---|---|
path | string | Required | API path, including query parameters when needed. |
init | RequestInit | Optional; GET when omitted | Fetch options, including body, method, headers, and cancellation signal. |
T | type parameter | Caller supplies the result type | A TypeScript assertion, not runtime response validation. |
Returns: RequestResult. Read ok before accessing the body.
The SDK adds authorization, JSON accept, and SDK user-agent headers. Each attempt
times out after 30 seconds.
Example
The listing endpoint returns listings and nextCursor. Use after with the
returned cursor to read another page. The default page size is 50; the maximum is 200.
import { Market, type Product } from "@metzia/sdk";
const market = new Market(process.env.METZIA_KEY, {
baseUrl: "https://sandbox.metzia.ai",
});
const result = await market.request<{
listings: Product[];
nextCursor: string | null;
}>("/api/v1/products?limit=50");
if (result.ok) {
console.log(result.body.listings);
} else {
console.log("Request failed:", result.code);
}Errors: HTTP failures, network failures, and unreadable response bodies return
values instead of exceptions. An invalid RequestInit, such as an invalid header,
can throw before the request starts.
Retry behavior: the method does not retry or add an idempotency key. A GET is safe to repeat. For a write, decide whether the API operation is idempotent first. A timeout or network failure does not prove that the server wrote nothing.
ProductsLink to this section
market.products.defineLink to this section
Validates a listing, checks its vocabulary terms, and sends it to
POST /api/v1/products. Requires catalog:write.
Signature
market.products.define(input: ListingInput, options?: DefineOptions): Promise<DefineResult>Parameters
| Name | Type | Required/default | Meaning |
|---|---|---|---|
input | ListingInput | Required | Listing fields. See Catalog fields for types, defaults, and constraints. |
options | DefineOptions | Optional | Your idempotency key and cancellation signal. |
Returns: DefineResult. A new product starts as draft.
This call does not publish a draft to buyers.
An update to a previously published listing can return pendingReview: true.
In that case, product is the live version, not the submitted change. Buyers keep
that version until staff approve the change. A newer submission replaces the
change that awaits review.
Example
This fragment assumes a configured market and a complete listing object.
The quickstart supplies both.
The result includes product, created, and pendingReview. Check created
to distinguish a new SKU from an update. Check pendingReview before treating
the returned product as your newly submitted version.
const result = await market.products.define(listing);
if (result.pendingReview) {
// The returned product is still the live version.
showReviewNotice(result.message);
} else {
showSavedProduct(result.product);
}The fragment also requires your showReviewNotice and showSavedProduct functions.
Errors
| Error | Cause | Next action |
|---|---|---|
| MarketValidationError | Invalid listing or unknown vocabulary term | Correct the named fields. |
| MarketNetworkError | Vocabulary request fails | Retry later; the SDK has not sent the listing. |
| MarketConflictError | HTTP 409 without Retry-After | Restore the original payload or use a new idempotency key. |
| MarketRetryError | HTTP 429, HTTP 409 with Retry-After, or server error | Wait, then check stored state or retry under the same key. |
| MarketRequestError | Other refusal, invalid idempotency key, unsupported runtime, unreadable response, or exhausted network retries | Read the message and verify the stored listing when the outcome is uncertain. |
| Signal reason | Caller aborts | Read stored state before sending another write. |
Retry behavior: automatic retries keep one idempotency key and one payload.
A separate define call generates a new key unless you pass options.idempotencyKey.
Use your own stable key when you need separate invocations to replay the same request.
Never reuse that key for a changed payload.
The seller and SKU identify one product, so a repeated call does not create a second product. A new call can still create a newer version. After an uncertain write or abort, read the listing before submitting another change.
Validation and vocabulary cache
Local validation runs before any request. Vocabulary validation then checks the category and integration slugs before sending the listing. The vocabulary cache is shared with market.vocabulary. A recently added term can remain unavailable until the cached list expires.
Retry timing and request limits
The SDK retries network failures up to three times. The waits are randomized within 100 to 200 ms, 200 to 400 ms, and 400 to 800 ms. After a network failure, it can also wait twice for an earlier attempt with the same key. One call sends at most six listing requests, plus a vocabulary request and its network retries when the cache needs a refresh.
validateListingLink to this section
Validates input locally and fills in defaults. It does not check the stored seller profile or fetch vocabulary terms.
Signature
validateListing(input: unknown): ListingParameters: input is required and can be any value.
Returns: Listing, with defaults applied.
Example
Use the error's errors array to show field-specific feedback. This complete
example passes an empty object to demonstrate a validation failure.
import { MarketValidationError, validateListing } from "@metzia/sdk";
try {
validateListing({});
} catch (error) {
if (!(error instanceof MarketValidationError)) throw error;
for (const problem of error.errors) {
console.log(problem.field, problem.rule, problem.message);
}
}Errors: MarketValidationError for invalid input.
Retry behavior: this function does not send a request or write state. Correct invalid input rather than validating it unchanged again.
A listing that passes local validation can still fail on the server. See the field rules and server checks below for the full validation requirements.
Field and cross-field rules
The field rulesLink to this section
Catalog fields is the field-by-field reference for
required values, types, lengths, numeric bounds, and defaults. Objects are
strict: an unknown field fails with rule unknown.
The SDK takes prices and tier bounds as safe JavaScript integers. It converts them to strings for the API. Prices use integer micro-units of USD; one dollar is 1000000 micro-units.
The notAFitWhen field is required. Describe known limits and disqualifiers:
a refund and a bad outcome can cost more than a lost sale.
Not a fit when gives examples.
The cross-field rulesLink to this section
See price point rules and subscription rules. These rules connect pricing models, tier bounds, plan names, recurring prices, and subscription terms.
Additional server validation
The server also checks these conditions:
- Blocked URLs return
blocked_domain. - Prose sanitization can return
shortened_below_floorortoo_many_removals. Other removals can occur without rejecting the listing. - Hostile injection content returns
injection_flagged. Suspect content records evidence without necessarily rejecting the listing. - Vocabulary checks can return
unknown_category,deprecated_category,unknown_limit_key, orunknown_integration. - The cancellation URL host must match the website domain in the seller profile.
Validation issue fields
The rule vocabularyLink to this section
Local validation issues use unknown, enum, format, too_short, min,
max, required, integer, type, url, or invalid in the rule field.
Server validation uses the server's error code instead. Read message when the
code is not listed here.
field is a wire path such as pricePoints.0.amountMicros. It is listing
when the issue refers to the whole listing.
listingSchemaLink to this section
The Zod schema used by validateListing.
Signature
listingSchema.safeParse(input: unknown): success/data or failure/errorParameters: required input of any type.
Returns: on success, data is a Listing with defaults. On failure,
error is a Zod error. The schema has the same field and cross-field rules as
validateListing.
Example
This complete example reports validation issues without throwing an exception.
import { listingSchema } from "@metzia/sdk";
const parsed = listingSchema.safeParse({});
if (!parsed.success) console.log(parsed.error.issues);Errors: safeParse reports validation failures in the result rather than
throwing MarketValidationError. The schema's parse method throws a Zod error
for invalid input.
Retry behavior: neither method sends a request or writes state.
VocabularyLink to this section
market.vocabularyLink to this section
Reads the active category and integration terms from GET /api/vocabulary.
Deprecated terms are absent.
market.vocabulary.categoriesLink to this section
Signature
market.vocabulary.categories(options?: { signal?: AbortSignal }): Promise<readonly VocabularyCategory[]>Parameters: optional options.signal cancels the request.
Returns: readonly VocabularyCategory objects, in the
order the server returns them.
Example
This complete example reads the active category slugs from the sandbox.
import { Market } from "@metzia/sdk";
const market = new Market(process.env.METZIA_KEY, {
baseUrl: "https://sandbox.metzia.ai",
});
const categories = await market.vocabulary.categories();
console.log(categories.map(({ slug }) => slug));Errors: MarketNetworkError after exhausted network retries or a server error; MarketRetryError for HTTP 429; MarketRequestError for other refusals or unreadable data. A caller abort raises the signal reason. Retry behavior: safe to repeat; the method is read-only. Network failures receive up to three automatic retries. Correct other refusals before retrying.
market.vocabulary.integrationsLink to this section
Signature
market.vocabulary.integrations(options?: { signal?: AbortSignal }): Promise<readonly VocabularyTerm[]>Parameters: optional options.signal cancels the request.
Returns: readonly VocabularyTerm objects, in server order.
Example
This complete example reads active integration slugs and display names from the sandbox.
import { Market } from "@metzia/sdk";
const market = new Market(process.env.METZIA_KEY, {
baseUrl: "https://sandbox.metzia.ai",
});
const integrations = await market.vocabulary.integrations();
console.log(integrations.map(({ slug, displayName }) => ({ slug, displayName })));Errors: the same classes and cancellation behavior as categories().
Retry behavior: safe to repeat; read-only, with up to three automatic network retries.
Concurrent reads share a request. The first caller's signal governs that shared request.
Shared vocabulary cache
Both methods share the cache used by define. The first read fetches the list;
reads within vocabularyTtlMs use memory. After expiry, the SDK sends If-None-Match
with its stored ETag; HTTP 304 renews the cached list.
Affiliate programsLink to this section
These methods require seller portal credentials. A sandbox catalog key does not
have affiliate permissions. All three take an optional { signal } options
object; an abort stops retries and raises the signal reason.
market.affiliate.registerLink to this section
Sets the commission terms for your affiliate program. Requires affiliate_program:write.
Signature
market.affiliate.register(input: AffiliateRegisterInput, options?: { signal?: AbortSignal }): Promise<AffiliateRegisterResult>Parameters
| Name | Type | Required/default | Meaning |
|---|---|---|---|
input | AffiliateRegisterInput | Required | Program ID, commission terms, link template, and optional attribution window. |
options.signal | AbortSignal | Optional | Cancels the request and its retries. |
Returns: AffiliateRegisterResult.
The returned programId is Metzia's version ID. networkProgramId is the ID you supplied.
Example
This fragment assumes market uses a seller portal key with the write permission.
rate: 2500 means 25 percent, not 2500 percent.
const program = await market.affiliate.register({
programId: "impact-4821",
rate: 2500,
term: "twelve_months",
linkTemplate: "https://impact.test/click?subId1={SUBID}",
attributionWindowDays: 30,
});Errors: MarketValidationError for invalid fields;
MarketRetryError for HTTP 429, server errors, or HTTP 409 with
code conflict; MarketRequestError for other refusals,
unreadable responses, or exhausted network retries. An abort raises the signal reason.
Retry behavior: up to three automatic network retries, without an idempotency
key. Equal stored terms produce changed: false and do not create a new version.
After a lost response, a retry can report changed: false even if the first
attempt changed the program. Read current terms with get().
market.affiliate.getLink to this section
Reads your current program. Requires affiliate_program:read.
Signature
market.affiliate.get(options?: { signal?: AbortSignal }): Promise<AffiliateProgram | null>Parameters: optional options.signal cancels the request.
Returns: AffiliateProgram, or null when no program exists.
Example fragment: use a client with the read permission.
const program = await market.affiliate.get();Errors: the same response/error mapping as register, including server-side
validation failures and the signal reason on abort.
Retry behavior: safe to repeat; read-only, with up to three automatic network retries.
market.affiliate.disableLink to this section
Ends your current program. Requires affiliate_program:write.
Signature
market.affiliate.disable(options?: { signal?: AbortSignal }): Promise<AffiliateDisableResult>Parameters: optional options.signal cancels the request.
Returns: AffiliateDisableResult. A second call returns
changed: false when no active program remains.
Example fragment: use a client with the write permission.
const result = await market.affiliate.disable();Errors: the same response/error mapping as register, including the signal
reason on abort. A suspended program returns program_suspended. Registering
terms on a suspended program returns program_inactive. Neither write succeeds.
Retry behavior: safe to repeat, with up to three automatic network retries.
Read the program after an uncertain response. To open a new version, register
terms and obtain staff approval; disable cannot enable a program.
WebhooksLink to this section
market.onLink to this section
Registers a handler for a seller event. A second registration for the same event replaces the first.
Signature
market.on("provision", handler: (event: ProvisionEvent) => ProvisionResult | Promise<ProvisionResult>): void
market.on("cancel", handler: (event: CancelEvent) => unknown): voidParameters
| Name | Type | Required/default | Meaning |
|---|---|---|---|
event | MarketEventName | Required | provision or cancel. |
handler | function | Required | Provision returns ProvisionResult. Cancel can return any result, including a promise. |
Returns: undefined. The receiver ignores the cancel handler's result but
waits for it to finish.
Example fragment: supply createAccount and revokeAccount in your application.
market.on("provision", async (event) => {
const account = await createAccount(event.buyerId, event.sku, event.orderId);
return { externalAccountId: account.id, created: account.created };
});
market.on("cancel", async (event) => {
await revokeAccount(event.externalAccountId, event.sku);
});Errors: Error for an unknown event or a handler that is not a function.
TypeScript callers cannot pass these values without bypassing the types.
Retry behavior: not applicable to registration. This method does not send a
request. The handlers themselves must tolerate duplicate callbacks.
market.webhooks.handlerLink to this section
Creates the receiver you mount in your application.
Signature
market.webhooks.handler(): (request: Request) => Promise<Response>Parameters: none. Configure webhookSecret on Market first.
Returns: a function that verifies the signature and dispatches a Web Request.
Example
This is complete receiver setup, not a complete provision/cancel integration. Register your handlers before serving callbacks, as in market.on.
import { Market } from "@metzia/sdk";
const market = new Market(process.env.METZIA_KEY, {
baseUrl: "https://sandbox.metzia.ai",
webhookSecret: process.env.METZIA_WEBHOOK_SECRET,
});
export const POST = market.webhooks.handler();Errors: creating the receiver throws Error if the signing secret is absent.
The receiver reports request failures as HTTP responses:
Receiver response statuses
| Status | Condition |
|---|---|
| 200 | Handler succeeds. Provision returns its account ID and created; cancel returns { ok: true }. |
| 400 | Unreadable body, invalid JSON, or unknown/invalid event. |
| 401 | Missing or invalid signature, or timestamp more than 300 seconds from the receiver's clock. |
| 500 | Missing handler, handler failure, invalid provision result, or signature-verification setup failure. |
Retry behavior: creating the receiver does not send a request. Metzia can
repeat callbacks after a failed or lost response. Keep both handlers idempotent.
Return the same account ID and created: false for a repeated provision.
Do not parse and reserialize the body before verification. The receiver must read the original bytes.
Signature format
The Metzia-Signature header has the format t=<unix seconds>,v1=<hex digest>.
HMAC-SHA256 covers <timestamp>.<raw body>.
TestingLink to this section
market certifyLink to this section
Checks duplicate provision, cancellation, and signature rejection against your running receiver. It creates test accounts, so run it against a test receiver.
Signature
market certify --url <receiver-url> --sku <known-sku> [options]Parameters
| Option | Required/default | Meaning |
|---|---|---|
--url | Required | Your running webhook receiver. |
--sku | Required | A SKU your handler recognizes. |
--secret | METZIA_WEBHOOK_SECRET | Signing secret. Prefer the environment variable. |
--key | METZIA_KEY | Platform key for reporting. Prefer the environment variable so the key does not appear in shell history or process arguments. |
--base-url | METZIA_BASE_URL, then DEFAULT_BASE_URL | Explicit report host. HTTPS is required except for local hosts. |
--no-report | Off | Run checks locally without reporting to Metzia. |
--help | Off | Show options. |
Returns: exit code 0 when all checks pass and any requested report succeeds; 1 for a failed check or report; 2 for a usage error.
Example: set your test receiver's secret in METZIA_WEBHOOK_SECRET first.
This command does not report to a platform host:
npx market certify --url http://localhost:3001/market --sku mailer-pro --no-report| Check | Expected result |
|---|---|
provision_answers | HTTP 200 with externalAccountId and created. |
provision_is_idempotent | Same account ID on repeat, with created: false. |
cancel_answers | HTTP 2xx for the created account. |
bad_signature_refused | HTTP 401 for an invalid signature. |
Errors: the command prints PASS or FAIL for each check. Receiver calls time
out after 10 seconds. A reporting failure produces exit code 1 even if receiver checks pass.
Retry behavior: another run creates a new test buyer and order, with IDs that
start with certify-. Remove test accounts after use. Repeating a run is not the
same as retrying one callback.
Reports are self-attested, not independent proof, and do not block a go-live request.
Report requirements and limits
Reports require all four checks. Metzia retains them for 90 days and accepts 20 reports per key per hour.
npx market --version prints the installed SDK version.
The package's CHANGELOG.md lists releases.
@metzia/sdk/testingLink to this section
Import test helpers from this subpath, not the main package. Use them in your tests rather than production receiver code.
signTestEventLink to this section
Creates a signed Web Request for a test. It does not send a network request.
Signature
signTestEvent(input: SignTestEventInput): Promise<Request>Parameters: required SignTestEventInput.
Returns: a POST Request with JSON body and a Metzia-Signature header.
Example
Run this complete example locally. It uses a fake platform key and calls the receiver directly, without contacting Metzia or the URL on the signed request.
Expect HTTP 200 and the response below. The fixed account ID is only a test fixture; it is not an account-creation implementation.
{"externalAccountId":"acct_test","created":false}import { Market } from "@metzia/sdk";
import { signTestEvent } from "@metzia/sdk/testing";
const market = new Market("osk_test_local_fixture", {
baseUrl: "https://sandbox.metzia.ai",
webhookSecret: "local-test-secret",
});
market.on("provision", () => ({ externalAccountId: "acct_test", created: false }));
const receiver = market.webhooks.handler();
const request = await signTestEvent({
secret: "local-test-secret",
event: {
type: "provision",
data: { buyerId: "byr_test", sku: "mailer-pro", orderId: "ord_test" },
},
});
const response = await receiver(request);
if (response.status !== 200) throw new Error("Receiver rejected the test event.");
console.log(response.status, await response.json());Errors: Error for an empty secret. Web Crypto or Web Request construction
can also fail for invalid configuration.
Retry behavior: signing is local and safe to repeat. If you dispatch the
request, your handler's idempotency rules apply.
Set timestamp to more than 300 seconds ago to test expiry; expect HTTP 401.
SignTestEventInputLink to this section
| Field | Type | Required/default | Meaning |
|---|---|---|---|
secret | string | Required, nonblank | Same signing secret as the receiver. |
event | { type, data } | Required | provision with ProvisionEvent, or cancel with CancelEvent. |
url | string | DEFAULT_TEST_URL | URL on the created request. The helper does not fetch it. |
timestamp | number | Current clock | Unix seconds. |
DEFAULT_TEST_URLLink to this section
Default request URL: https://example.test/metzia-webhooks.
MISSING_TEST_SECRET_MESSAGELink to this section
Empty-secret error text: signTestEvent needs a non-empty webhook signing secret.
ErrorsLink to this section
Every SDK error has name, message, and toJSON(). The SDK does not write logs;
your application decides what to record. Do not log keys or signing secrets.
MarketValidationErrorLink to this section
Invalid listing or affiliate input. errors is a readonly array of
MarketValidationIssue. Local validation fails before
a request; server validation can fail after a request. Correct the fields before retrying.
MarketConflictErrorLink to this section
A product request returned HTTP 409 without Retry-After. sku identifies the
listing. The idempotency key already refers to another payload. Restore the
original payload or use a new key for the changed payload.
MarketRetryErrorLink to this section
| Field | Type | Meaning |
|---|---|---|
status | number | HTTP response status. |
retryAfterSeconds | number or null | Server-specified wait, or null when no wait is supplied. |
HTTP 429 rejects the call before a write. Other retryable responses can leave the write outcome uncertain. Follow the method's retry rules; this error does not mean every method uses an idempotency key.
MarketNetworkErrorLink to this section
Vocabulary lookup failed after network retries, or the server returned an error.
The SDK did not send the listing. Retry later. This class extends
MarketRequestError, with the same status and code fields.
MarketRequestErrorLink to this section
| Field | Type | Meaning |
|---|---|---|
status | number or null | HTTP status, or null when no response arrived. |
code | string or null | Metzia error code when available. |
Other refusals, invalid configuration, exhausted network retries, or unreadable responses. Read the message for the next action. A failed write can still have reached the server; verify stored state before sending another write.
TypesLink to this section
MarketOptionsLink to this section
| Field | Type | Required/default | Constraint or meaning |
|---|---|---|---|
baseUrl | string | DEFAULT_BASE_URL | Absolute URL without query or fragment. Set explicitly for each environment. |
webhookSecret | string | Optional; required for receiver setup | Signing secret for inbound callbacks. Blank values count as absent. |
vocabularyTtlMs | number | DEFAULT_VOCABULARY_TTL_MS | Nonnegative safe integer, in milliseconds. Zero refreshes on each read. |
ListingInputLink to this section
Input for define and validateListing. Fields with defaults are optional.
Catalog fields lists every field, type, default, and constraint.
ListingLink to this section
Validated input with defaults filled in. description and subscription default
to null; limits to {}; integrations to []; isSubscription to false.
Nested price and subscription defaults are in Catalog fields.
DefineOptionsLink to this section
| Field | Type | Required/default | Constraint or meaning |
|---|---|---|---|
idempotencyKey | string | Generated for each call | 1 to 255 visible ASCII characters after trimming. Reuse only for the same payload and replay scope. |
signal | AbortSignal | Optional | Cancels requests and retry waits. A write may already have reached the server. |
DefineResultLink to this section
| Field | Type | Presence | Meaning |
|---|---|---|---|
product | Product | Always | Saved product, or the live version when a change awaits review. |
created | boolean | Always | True for a new product, false for an existing SKU. |
pendingReview | boolean | Always; SDK defaults to false | True when a submitted change awaits staff review. |
submittedAt | string | Optional | ISO timestamp of the submitted change. |
message | string | Optional | Explanation of the review state. |
ProductLink to this section
| Field | Type | Presence | Meaning |
|---|---|---|---|
id | string | Always | Metzia product ID. |
sku | string | Always | Seller-supplied SKU. |
name | string | Always | Stored name. |
status | string | Always | draft for a new product; updates do not publish it. |
version | number | Always | Stored version number. |
syncedAt | string or null | Always | Last sync time, as ISO text when available. |
ProductSurfaceLink to this section
The type of market.products. Contains define.
ProvisionEventLink to this section
| Field | Type | Required | Meaning |
|---|---|---|---|
buyerId | string | Yes | Buyer join key, never an email address. |
sku | string | Yes | Product SKU. |
orderId | string | Yes | Order key used for idempotent provision. |
ProvisionResultLink to this section
| Field | Type | Required | Meaning |
|---|---|---|---|
externalAccountId | string | Yes; nonblank | Account ID in your system. |
created | boolean | Yes | True if this attempt created the account; false for an existing account or duplicate callback. |
CancelEventLink to this section
| Field | Type | Required | Meaning |
|---|---|---|---|
externalAccountId | string | Yes | Account ID returned by provision. |
sku | string | Yes | Product to revoke. |
MarketEventNameLink to this section
provision or cancel. Other names fail TypeScript compilation.
AffiliateRegisterInputLink to this section
| Field | Type | Required/default | Constraint or meaning |
|---|---|---|---|
programId | string | Required | Network program ID, 1 to 200 characters after trimming. |
rate | number | Required | Integer basis points from 1 to 10000. One percent is 100. |
term | AffiliateTerm | Required | Commission duration. |
linkTemplate | string | Required | Absolute HTTPS URL, at most 2000 characters after trimming, with {SUBID} or {subid}. |
attributionWindowDays | number | Optional; 30 on first registration | Integer from 1 to 365. |
The link template must not contain spaces, control characters, or a supported
macro after #. Supported macros are SUBID, DEST, and CLICKID, regardless of case.
AffiliateRegisterResultLink to this section
| Field | Type | Presence | Meaning |
|---|---|---|---|
programId | string | Always | Metzia ID for this program version. |
networkProgramId | string | Always | Network ID supplied in the request. |
changed | boolean | Always | False when terms match the stored program. |
status | AffiliateProgramState | Always | Current state. |
approvalRequired | boolean | Always | True when status is not approved. |
AffiliateProgramLink to this section
| Field | Type | Presence | Meaning |
|---|---|---|---|
programId | string | Always | Metzia program version ID. |
networkProgramId | string or null | Always | Network program ID, when stored. |
rate | number or null | Always | Basis points; null for a fixed-amount program. |
term | AffiliateTerm or other | Always | other means a stored duration outside the SDK vocabulary. |
linkTemplate | string | Always | Stored referral template. |
confirmedAt | string or null | Always | ISO timestamp of approval, or null before approval. |
status | AffiliateProgramState | Always | Current state. |
AffiliateDisableResultLink to this section
| Field | Type | Presence | Meaning |
|---|---|---|---|
programId | string or null | Always | Ended program, or null when none exists. |
changed | boolean | Always | False when no active program existed. |
AffiliateTermLink to this section
One of AFFILIATE_TERMS.
AffiliateProgramStateLink to this section
One of AFFILIATE_PROGRAM_STATES.
AffiliateSurfaceLink to this section
The type of market.affiliate. Contains register, get, and disable.
VocabularySurfaceLink to this section
The type of market.vocabulary. Contains categories and integrations.
VocabularyTermLink to this section
| Field | Type | Presence | Meaning |
|---|---|---|---|
slug | string | Always, readonly | Integration identifier. |
displayName | string | Always, readonly | Human-readable name. |
VocabularyCategoryLink to this section
Has the readonly fields of VocabularyTerm, plus:
| Field | Type | Presence | Meaning |
|---|---|---|---|
parent | string or null | Always, readonly | Parent category slug, or null. |
MarketValidationIssueLink to this section
| Field | Type | Presence | Meaning |
|---|---|---|---|
field | string | Always, readonly | Stable wire path. |
rule | string | Always, readonly | Local rule or server validation code. |
message | string | Always, readonly | Description of the problem. |
RequestResultLink to this section
A discriminated union. Check ok, then code for failures.
| Variant | Fields | Meaning |
|---|---|---|
ok: true | status: number, body: T, optional etag: string | HTTP 2xx; parsed JSON, or undefined body for an empty response. T is not validated. |
ok: false, code: "network" | error: unknown | Request did not complete, including timeout or abort. No HTTP status is available. |
ok: false, code: "http" | status: number, body: string, retryAfterSeconds: number | null | Non-2xx response. Body is raw text. |
ok: false, code: "body" | status: number, body: string | HTTP 2xx with unreadable or non-JSON body. |
ConstantsLink to this section
DEFAULT_BASE_URLLink to this section
Default client host: https://api.metzia.ai. Set baseUrl explicitly rather than
relying on this value. Sandbox examples use https://sandbox.metzia.ai.
DEFAULT_VOCABULARY_TTL_MSLink to this section
Default cache lifetime: 3600000 milliseconds, one hour.
VOCABULARY_PATHLink to this section
Vocabulary route: /api/vocabulary.
SLUG_PATTERNLink to this section
Category and integration slug pattern: 1 to 63 lowercase letters, digits, and hyphens, starting and ending with a letter or digit.
PRICING_MODELSLink to this section
flat, seat, usage, and tiered.
DELIVERSLink to this section
seats, credits, api_key, license, access, and shipment.
PROVISIONING_TIERSLink to this section
delegated, keyless, and claim.
PRICE_INTERVALSLink to this section
month and year.
PRICE_POINT_TEXT_LIMITSLink to this section
plan: 80 characters. unitName: 40 characters.
PRODUCT_TEXT_LIMITSLink to this section
summary: 280 characters. description: 4000 characters.
notAFitWhenMin: 40 characters. notAFitWhen: 1000 characters.
BILLING_INTERVALSLink to this section
monthly, annual, and other.
RENEWAL_BEHAVIOURSLink to this section
auto_renews, manual_renewal, and one_time.
SUBSCRIPTION_LIMITSLink to this section
cancellationUrl: 2048 characters. freeTrialDaysMax: 365 days.
renewalTermsMin: 40 code points. renewalTerms: 600 code points.
AFFILIATE_TERMSLink to this section
life_of_account: commission on each invoice. twelve_months: commission for
twelve months. first_invoice: commission once.
AFFILIATE_PROGRAM_STATESLink to this section
not_started, applied, approved, rejected, terminated, and inactive.
The first five describe enrollment. inactive means staff suspended or ended
the program. Commission runs only when the state is approved.
For setup and verification, see the seller quickstart.
Updated 2026-10-14