{"templateId":"markdown","versions":[{"version":"1.0","label":"v1.0","link":"/omni-api/overview/quickstart","default":true,"active":true,"folderId":"6bec560c"}],"sharedDataIds":{"sidebar":"sidebar-omni-api/@1.0/overview/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Quickstart","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"quickstart","__idx":0},"children":["Quickstart"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This walkthrough validates authentication, catalog access, file upload, and result delivery in sandbox."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"1-prepare-credentials","__idx":1},"children":["1. Prepare credentials"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Obtain the sandbox API token, confirm the calling IP is allowlisted, and configure a public HTTPS webhook endpoint with Percents."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"export PERCENTS_API_BASE='https://sandbox.percents.com'\nexport PERCENTS_API_TOKEN='tok_your_id:api_your_secret'\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"2-read-merchants-and-offers","__idx":2},"children":["2. Read merchants and offers"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl --fail-with-body \\\n  --header \"Authorization: token ${PERCENTS_API_TOKEN}\" \\\n  \"${PERCENTS_API_BASE}/api/v1/omni/merchant\"\n\ncurl --fail-with-body \\\n  --header \"Authorization: token ${PERCENTS_API_TOKEN}\" \\\n  \"${PERCENTS_API_BASE}/api/v1/omni/offer\"\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Persist merchant and offer UUIDs exactly as returned. Do not infer access to a merchant from its name."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"3-request-a-plaid-upload-url","__idx":3},"children":["3. Request a Plaid upload URL"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl --fail-with-body --get \\\n  --header \"Authorization: token ${PERCENTS_API_TOKEN}\" \\\n  --data-urlencode 'content=plaid-txn-stream' \\\n  --data-urlencode 'fileType=json' \\\n  --data-urlencode 'fileName=transactions-2026-08-10.json' \\\n  \"${PERCENTS_API_BASE}/api/fileUpload\"\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The response contains a presigned URL that expires after 15 minutes:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"url\": \"https://object-storage.example/presigned-upload\"\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"4-upload-the-file","__idx":4},"children":["4. Upload the file"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"curl --fail-with-body \\\n  --request PUT \\\n  --header 'Content-Type: application/json' \\\n  --data-binary @transactions.json \\\n  'PRESIGNED_URL_FROM_THE_PREVIOUS_RESPONSE'\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Do not send the Percents API token to the presigned URL. The URL itself grants temporary permission to upload that single object."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"5-receive-the-result","__idx":5},"children":["5. Receive the result"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Return a successful ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["2xx"]}," response after validating the webhook signature and durably recording the event. Process each ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["webhookId"]}," idempotently."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["During regular periodic file processing, which runs no less frequently than hourly, Percents downloads and validates the complete file and sends ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FileUploadSchemaValidation"]},". A passing result acknowledges the file contract only; it is not an audit or reward result."]}]},"headings":[{"value":"Quickstart","id":"quickstart","depth":1},{"value":"1. Prepare credentials","id":"1-prepare-credentials","depth":2},{"value":"2. Read merchants and offers","id":"2-read-merchants-and-offers","depth":2},{"value":"3. Request a Plaid upload URL","id":"3-request-a-plaid-upload-url","depth":2},{"value":"4. Upload the file","id":"4-upload-the-file","depth":2},{"value":"5. Receive the result","id":"5-receive-the-result","depth":2}],"frontmatter":{"seo":{"title":"Quickstart"}},"lastModified":"2026-08-11T03:50:30.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/omni-api/overview/quickstart","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}