ZeroVisual Offers API

Use this API to retrieve monetization offers based on user intent and context from your application.

Overview

ZeroVisual analyzes user intent (for example, a search query, chat question or forum message) and returns a list of relevant offers: coupons, deals, products, and sponsored links. You send a short text description of what the user is doing, and optionally anactionthat describes the user action, and get back structured offers ready to display in your product.

Base URL (example)

https://api.zyntent.ai

Authentication

The API uses API keys with Bearer authentication.

  • Send your key in theAuthorizationheader.
  • Format:Authorization: Bearer YOUR_API_KEY

Endpoint: Get Offers by Intent

POST/api/v1/offers

Send user intent and optional context, receive a ranked list of monetization offers.

Request

Headers

  • Content-Type:application/json
  • Authorization:Bearer YOUR_API_KEY

Body (JSON)

{
  "intent": "buy iphone 15 pro in Berlin",
  "action": "Typing a search query",
  "limit": 5,
  "locale": "de-DE",
  "currency": "EUR",
  "user_id": "optional-user-id",
  "source": "llm_app" 
}
FieldTypeRequiredDescription
intentstringYesShort natural language description of what the user wants or is doing (query, message, question, etc.).
actionstringNoOptional description of the user action. Examples: "Typing a search query", "Sending a message to a forum thread", "Sending a question to chat", "Receiving a response from chat".
limitintegerNoMaximum number of offers to return. Default is typically 3.
localestringNoUser locale in IETF format (e.g. "en-US", "de-DE") to improve geo/language targeting.
currencystringNoPreferred currency code (ISO 4217), for example "EUR" or "USD".
user_idstringNoOptional stable internal user identifier on your side, used for attribution and frequency capping.
sourcestringNoOptional short identifier of integration type. Examples: "llm_app", "search_suggest", "forum_widget", "telegram_bot".

Successful Response (200)

{
  "request_id": "f4b1a0d2-23c5-4d0d-9e5b-9f8a2c8eaa01",
  "intent": {
    "raw": "buy iphone 15 pro in Berlin",
    "normalized": "buy iphone 15 pro in berlin",
    "category": "electronics",
    "commercial": true,
    "language": "en",
    "confidence": 0.97
  },
  "offers": [
    {
      "id": "offer_123",
      "title": "iPhone 15 Pro 128GB",
      "description": "Official Apple Store DE",
      "url": "https://example.com/iphone-15-pro",
      "merchant": "Apple",
      "price": 1199.99,
      "currency": "EUR",
      "discount": {
        "type": "coupon",
        "code": "APPLE10",
        "value": 10,
        "value_type": "percent"
      },
      "tracking_url": "https://trk.zyntent.ai/click/offer_123?...",
      "expires_at": "2025-01-31T23:59:59Z"
    }
  ]
}

Error Responses

StatusError codeDescription
400 Bad Requestinvalid_requestMissing or invalid fields (for example, emptyintent).
401 Unauthorizedinvalid_api_keyAPI key is missing, expired or invalid.
429 Too Many Requestsrate_limitedThe client has sent too many requests in a short period of time.
500 Internal Server Errorinternal_errorUnexpected error on the server side. Retry the request or contact support.
{
  "error": "invalid_request",
  "message": "Field 'intent' is required"
}

Usage Examples

Below are minimal examples of how to call the API from different environments.

curl

curl -X POST https://api.zyntent.ai/api/v1/offers   -H "Authorization: Bearer YOUR_API_KEY"   -H "Content-Type: application/json"   -d '{
    "intent": "Find cheap flights from Berlin to Paris",
    "action": "Typing a search query",
    "limit": 3,
    "source": "search_suggest"
  }'

Node.js (fetch)

const response = await fetch("https://api.zyntent.ai/api/v1/offers", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    intent: "User is sending a message to a forum thread about gaming laptops",
    action: "Sending a message to a forum thread",
    limit: 4,
    source: "forum_widget",
  }),
});

const data = await response.json();
console.log(data.offers);

About the action field

The action field is optional but highly recommended. It tells ZeroVisual what exactly the user is doing at the moment when you request offers. This helps the system choose the best format and type of offers.

Examples:

  • "Typing a search query" (search suggest integrations)
  • "Sending a message to a forum thread" (forum widgets)
  • "Sending a question to chat" (LLM chat input)
  • "Receiving a response from chat" (LLM answer post-processing)

You can use any free-form English description that best matches your product. If you do not send the field, the system will still work, but intent detection may be less precise for some edge cases.