{"templateId":"markdown","versions":[{"version":"1.0","label":"1.0","link":"/omni-api/1.0/changelog/releases/v1.0","default":false,"active":false,"folderId":"6bec560c"},{"version":"1.1","label":"1.1","link":"/omni-api/1.1/changelog/releases/v1.0","default":false,"active":false,"folderId":"6bec560c"},{"version":"1.2","label":"1.2","link":"/omni-api/changelog/releases/v1.0","default":true,"active":true,"folderId":"6bec560c"}],"sharedDataIds":{"sidebar":"sidebar-omni-api/@1.0/changelog/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"1.0"},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"10","__idx":0},"children":["1.0"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"API version"},"children":["API version"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Status"},"children":["Status"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Most recent API update"},"children":["Most recent API update"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["1.0"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Previous"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["November 17, 2025"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Version 1.0 was the initial public Omni API contract. This release note describes its November 17, 2025 update."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"public-api-scope","__idx":1},"children":["Public API scope"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Read current, upcoming, and historical issuer-scoped offers."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Read current and historical merchants by issuer scope."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Request a short-lived presigned URL for an enabled transaction-file content contract."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Upload the public ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["plaid-txn-stream"]}," JSON format."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Receive the signed ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FileUploadSchemaValidation"]}," webhook after complete file-schema validation."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Read each merchant's authoritative ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["new"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["lapsed"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loyal"]}," transaction-history definitions from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["segmentDefinitions"]},"."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"authentication-and-tenant-scope","__idx":2},"children":["Authentication and tenant scope"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["API calls use an issuer-owned server-side credential:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"http","header":{"controls":{"copy":{}}},"source":"Authorization: token <token-id>:<token-secret>\n","lang":"http"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This is not Bearer authentication. Percents resolves the credential to an issuer. Clients do not send an issuer identifier."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"offer-immutability","__idx":3},"children":["Offer immutability"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Published offers are immutable after creation except for ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["endDate"]},". Percents may change that end date to extend, shorten, or end an offer. A change to any other term creates a new offer with a new UUID."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The offer contract includes spatial condition, cardholder and publisher rates, calendar-only start and end dates, minimum spend, maximum earn, maximum transaction value, maximum redemptions, a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["segment"]}," of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["new"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loyal"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["lapsed"]},", or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]},", a required customer-facing description, and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["rateIsPercent"]},". ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["rateIsPercent"]}," controls the units of both rate fields: both are basis-point percentages when true and minor-unit fixed amounts when false."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"plaid-file-upload-contract","__idx":4},"children":["Plaid file upload contract"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["plaid-txn-stream"]}," is the only publicly documented ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["content"]}," value. It requires a JSON envelope containing ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactions"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["accounts"]}," arrays. Every transaction requires ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["percentsMerchantId"]}," and a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["segment"]}," value of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["new"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loyal"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["lapsed"]},", or JSON ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]},". Other content values may exist only under private partner agreements."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Requesting a presigned URL and uploading bytes are separate steps. The storage ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PUT"]}," does not mean processing has completed."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"schema-validation-webhook","__idx":5},"children":["Schema validation webhook"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["During regular periodic file processing, which runs no less frequently than hourly, Percents downloads each Plaid JSON upload from storage and validates its complete envelope and constituent rows. It then sends ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FileUploadSchemaValidation"]}," with the filename, discovered row count, pass/fail result, and nullable ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["errorMetadata"]},". Every transaction account must be represented in the top-level ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["accounts"]}," array; missing IDs are returned in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["errorMetadata.missingAccountIds"]},". Unknown merchant UUIDs are returned in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["errorMetadata.unknownPercentsMerchantIds"]},". One invalid row fails the file atomically and prevents ingestion. This event does not report transaction audits or reward outcomes."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Receivers verify ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["X-Percents-Signature"]}," with the separately issued ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sign_"]}," token, persist the result, deduplicate by ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["webhookId"]},", and return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["2xx"]}," promptly."]}]},"headings":[{"value":"1.0","id":"10","depth":1},{"value":"Public API scope","id":"public-api-scope","depth":2},{"value":"Authentication and tenant scope","id":"authentication-and-tenant-scope","depth":2},{"value":"Offer immutability","id":"offer-immutability","depth":2},{"value":"Plaid file upload contract","id":"plaid-file-upload-contract","depth":2},{"value":"Schema validation webhook","id":"schema-validation-webhook","depth":2}],"frontmatter":{"seo":{"title":"1.0"}},"lastModified":"2026-10-02T20:53:32.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/omni-api/changelog/releases/v1.0","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}