> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mazeedplus.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Placements API

> Request personalized content and offers for your users

The Placements API returns personalized content and offers based on user context and behavior. Use this API to display targeted promotions, product recommendations, and custom offers at key moments in your user journey.

## Endpoint

```
POST https://api.mazeedplus.com/select-placement
```

## Authentication

Authenticate your requests by including your API key in the `x-publishable-api-key` header.

```
x-publishable-api-key: pk_live_51H7...
```

## Create a placement

Creates a personalized placement for display to your users.

### Parameters

<ParamField body="identifier" type="string" required>
  Unique identifier for the placement (e.g., "home-page", "checkout\_success")
</ParamField>

<ParamField body="attributes" type="object" required>
  User and transaction data for personalization

  <Expandable title="Customer Information">
    <ParamField body="userId" type="string" required>
      Unique customer identifier from your system
    </ParamField>

    <ParamField body="mobile" type="string" optional>
      Customer mobile phone number with country code (e.g., "+966501234567" for Saudi Arabia, "+971501234567" for UAE, "+201001234567" for Egypt)
    </ParamField>

    <ParamField body="firstname" type="string" optional>
      Customer first name
    </ParamField>

    <ParamField body="lastname" type="string" optional>
      Customer last name
    </ParamField>

    <ParamField body="age" type="number" optional>
      Customer age in years
    </ParamField>

    <ParamField body="gender" type="string" optional>
      Customer gender ("male" or "female")
    </ParamField>

    <ParamField body="interests" type="array" optional>
      Array of customer interests and brand preferences (e.g., \["technology", "fitness", "brand:Nike", "brand:Apple"])
    </ParamField>

    <ParamField body="country" type="string" optional>
      Two-letter country code (ISO 3166-1 alpha-2)
    </ParamField>

    <ParamField body="language" type="string" optional>
      Two-letter language code (ISO 639-1)
    </ParamField>
  </Expandable>

  <Expandable title="Transaction Data">
    <ParamField body="currency" type="string" optional>
      Three-letter currency code (ISO 4217)
    </ParamField>

    <ParamField body="confirmationref" type="string" optional>
      Order confirmation reference
    </ParamField>

    <ParamField body="paymenttype" type="string" optional>
      Payment method used
    </ParamField>

    <ParamField body="cartItems" type="string" optional>
      JSON string of cart contents for cross-sell analysis
    </ParamField>
  </Expandable>

  <Expandable title="Search">
    <ParamField body="q" type="string" optional>
      Search query to find relevant products
    </ParamField>
  </Expandable>
</ParamField>

### Returns

The response format depends on the `Accept` header:

#### JSON Response (default)

When `Accept: application/json` or no specific HTML accept header is provided, returns a placement object.

#### HTML Response

When `Accept: text/html` is provided, returns an HTML document directly in the response body with `Content-Type: text/html`.

<ResponseField name="identifier" type="string">
  Unique identifier for this placement
</ResponseField>

<ResponseField name="templateName" type="string">
  Name of the template used for rendering
</ResponseField>

<ResponseField name="template_data" type="object">
  Structured data for native rendering

  <Expandable title="data properties">
    <ResponseField name="entities" type="array">
      Array of content entities

      <Expandable title="Entity Types">
        <ResponseField name="Collection Entity" type="object">
          Groups related products together

          <Expandable title="Collection properties">
            <ResponseField name="object" type="string">
              Always "collection"
            </ResponseField>

            <ResponseField name="id" type="string">
              Unique collection identifier
            </ResponseField>

            <ResponseField name="name" type="string">
              Collection display name
            </ResponseField>

            <ResponseField name="items" type="array">
              Array of product references

              <Expandable title="Item reference">
                <ResponseField name="ref" type="string">
                  Product ID reference
                </ResponseField>
              </Expandable>
            </ResponseField>
          </Expandable>
        </ResponseField>

        <ResponseField name="Product Entity" type="object">
          Individual product for display

          <Expandable title="Product properties">
            <ResponseField name="object" type="string">
              Always "product"
            </ResponseField>

            <ResponseField name="id" type="string">
              Unique product identifier
            </ResponseField>

            <ResponseField name="title" type="string">
              Product name
            </ResponseField>

            <ResponseField name="description" type="string">
              Product description (optional)
            </ResponseField>

            <ResponseField name="price" type="object">
              Pricing information

              <Expandable title="Price object">
                <ResponseField name="amount" type="number">
                  Price
                </ResponseField>

                <ResponseField name="currency" type="string">
                  Three-letter currency code
                </ResponseField>
              </Expandable>
            </ResponseField>

            <ResponseField name="compare_price" type="object">
              Original price for discounted items (optional)
            </ResponseField>

            <ResponseField name="media" type="array">
              Product images and media

              <Expandable title="Media object">
                <ResponseField name="role" type="string">
                  Media role ("primary" or "secondary")
                </ResponseField>

                <ResponseField name="uri" type="string">
                  Media URL
                </ResponseField>

                <ResponseField name="content_type" type="string">
                  MIME type (e.g., "image/jpeg")
                </ResponseField>
              </Expandable>
            </ResponseField>

            <ResponseField name="brand" type="string">
              Product brand (optional)
            </ResponseField>

            <ResponseField name="category" type="string">
              Product category (optional)
            </ResponseField>

            <ResponseField name="click_url" type="string">
              Product purchase/detail page URL
            </ResponseField>

            <ResponseField name="rating" type="object">
              Customer ratings (optional)

              <Expandable title="Rating object">
                <ResponseField name="average" type="number">
                  Average rating (1-5)
                </ResponseField>

                <ResponseField name="count" type="number">
                  Number of reviews
                </ResponseField>
              </Expandable>
            </ResponseField>
          </Expandable>
        </ResponseField>

        <ResponseField name="Incentive Entity" type="object">
          Promotional incentive or discount

          <Expandable title="Incentive properties">
            <ResponseField name="object" type="string">
              Always "incentive"
            </ResponseField>

            <ResponseField name="id" type="string">
              Unique incentive identifier
            </ResponseField>

            <ResponseField name="kind" type="string">
              Incentive type ("cart\_credit", "discount\_percentage", "discount\_fixed", "free\_shipping")
            </ResponseField>

            <ResponseField name="value" type="object">
              Incentive value information

              <Expandable title="Value object">
                <ResponseField name="amount" type="number">
                  Value amount
                </ResponseField>

                <ResponseField name="currency" type="string">
                  Currency code
                </ResponseField>
              </Expandable>
            </ResponseField>

            <ResponseField name="title" type="string">
              Incentive display title
            </ResponseField>

            <ResponseField name="description" type="string">
              Incentive description (optional)
            </ResponseField>
          </Expandable>
        </ResponseField>

        <ResponseField name="Creative Entity" type="object">
          Visual content or messaging

          <Expandable title="Creative properties">
            <ResponseField name="object" type="string">
              Always "creative"
            </ResponseField>

            <ResponseField name="id" type="string">
              Unique creative identifier
            </ResponseField>

            <ResponseField name="title" type="string">
              Creative headline (optional)
            </ResponseField>

            <ResponseField name="content" type="string">
              Text content or message
            </ResponseField>

            <ResponseField name="media" type="array">
              Creative media (optional)

              <Expandable title="Media object">
                <ResponseField name="role" type="string">
                  Media role ("primary" or "secondary")
                </ResponseField>

                <ResponseField name="uri" type="string">
                  Media URL
                </ResponseField>

                <ResponseField name="content_type" type="string">
                  MIME type (e.g., "image/jpeg")
                </ResponseField>
              </Expandable>
            </ResponseField>

            <ResponseField name="video_url" type="string">
              Creative video URL (optional)
            </ResponseField>

            <ResponseField name="cta" type="object">
              Call-to-action button (optional)

              <Expandable title="CTA object">
                <ResponseField name="text" type="string">
                  Button text
                </ResponseField>

                <ResponseField name="click_url" type="string">
                  Button destination URL
                </ResponseField>
              </Expandable>
            </ResponseField>
          </Expandable>
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="rendered_at" type="string">
  ISO timestamp of when the placement was rendered
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl https://api.mazeedplus.com/select-placement \
    -H "x-publishable-api-key: pk_live_51H7..." \
    -H "Content-Type: application/json" \
    -d '{
      "identifier": "checkout_success",
      "attributes": {
        "userId": "user_123456789",
        "mobile": "+966501234567",
        "currency": "sar",
        "country": "sa",
        "firstname": "Ahmed",
        "lastname": "Ali",
        "interests": ["technology", "gaming", "brand:Nike", "brand:Apple"],
        "q": "كولومبي قهوه"
      }
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://api.mazeedplus.com/select-placement", {
    method: "POST",
    headers: {
      "x-publishable-api-key": "pk_live_51H7...",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      identifier: "checkout_success",
      attributes: {
        userId: "user_123456789",
        mobile: "+966501234567",
        currency: "sar",
        country: "sa",
        firstname: "Ahmed",
        lastname: "Ali",
        interests: ["technology", "gaming", "brand:Nike", "brand:Apple"],
        q: "كولومبي قهوه",
      },
    }),
  });

  const placement = await response.json();
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.mazeedplus.com/select-placement",
      headers={
          "x-publishable-api-key": "pk_live_51H7...",
          "Content-Type": "application/json"
      },
      json={
          "identifier": "checkout_success",
          "attributes": {
              "userId": "user_123456789",
              "mobile": "+966501234567",
              "currency": "sar",
              "country": "sa",
              "firstname": "Ahmed",
              "lastname": "Ali",
              "interests": ["technology", "gaming", "brand:Nike", "brand:Apple"],
              "q": "كولومبي قهوه"
          }
      }
  )

  placement = response.json()
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init('https://api.mazeedplus.com/select-placement');
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'x-publishable-api-key: pk_live_51H7...',
      'Content-Type: application/json'
  ]);
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
      'identifier' => 'checkout_success',
      'attributes' => [
          'userId' => 'user_123456789',
          'mobile' => '+966501234567',
          'currency' => 'sar',
          'country' => 'sa',
          'firstname' => 'Ahmed',
          'lastname' => 'Ali',
          'interests' => ['technology', 'gaming', 'brand:Nike', 'brand:Apple'],
          'q' => 'كولومبي قهوه'
      ]
  ]));
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

  $response = curl_exec($ch);
  $placement = json_decode($response, true);
  curl_close($ch);
  ?>
  ```
</RequestExample>

<ResponseExample>
  ```json Success theme={null}
  {
    "identifier": "checkout_success",
    "templateName": "Product Listing",
    "template_data": {
      "entities": [
        {
          "object": "collection",
          "id": "col_featured",
          "name": "Featured Products",
          "items": [
            { "ref": "prod_1234" },
            { "ref": "prod_5678" },
            { "ref": "prod_9012" }
          ]
        },
        {
          "object": "product",
          "id": "prod_1234",
          "title": "Wireless Headphones",
          "description": "High-quality wireless headphones with active noise cancellation and 30-hour battery life",
          "price": {
            "amount": 8999,
            "currency": "usd"
          },
          "media": [
            {
              "role": "primary",
              "uri": "https://example.com/headphones.jpg",
              "content_type": "image/jpeg"
            }
          ],
          "click_url": "https://checkout.mazeedplus.com/p/prod_1234"
        },
        {
          "object": "product",
          "id": "prod_5678",
          "title": "Smartphone Case",
          "description": "Premium protective case with shock-absorbing design",
          "price": {
            "amount": 2499,
            "currency": "usd"
          },
          "media": [
            {
              "role": "primary",
              "uri": "https://example.com/case.jpg",
              "content_type": "image/jpeg"
            }
          ],
          "click_url": "https://checkout.mazeedplus.com/p/prod_5678"
        },
        {
          "object": "product",
          "id": "prod_9012",
          "title": "Charging Cable",
          "description": "Fast-charging USB-C cable with braided nylon design",
          "price": {
            "amount": 1999,
            "currency": "usd"
          },
          "media": [
            {
              "role": "primary",
              "uri": "https://example.com/cable.jpg",
              "content_type": "image/jpeg"
            }
          ],
          "click_url": "https://checkout.mazeedplus.com/p/prod_9012"
        },
        {
          "object": "incentive",
          "id": "inc_abc123",
          "kind": "free_shipping",
          "value": {
            "amount": 0,
            "currency": "usd"
          },
          "title": "Free Shipping",
          "description": "Free shipping on orders over $50"
        }
      ]
    }
  }
  ```

  ```json Validation Error - Missing Required Fields theme={null}
  {
    "error": "Validation failed",
    "error_code": "VALIDATION_ERROR",
    "message": "Invalid request data",
    "details": {
      "_errors": [],
      "identifier": {
        "_errors": [
          "Required"
        ]
      }
    }
  }
  ```

  ```json Validation Error - Missing userId theme={null}
  {
    "error": "Validation failed",
    "error_code": "VALIDATION_ERROR",
    "message": "Invalid request data",
    "details": {
      "_errors": [],
      "attributes": {
        "_errors": [],
        "userId": {
          "_errors": [
            "User ID is required"
          ]
        }
      }
    }
  }
  ```

  ```json Validation Error - Invalid Mobile Number theme={null}
  {
    "error": "Validation failed",
    "error_code": "VALIDATION_ERROR",
    "message": "Invalid request data",
    "details": {
      "_errors": [],
      "attributes": {
        "_errors": [],
        "mobile": {
          "_errors": [
            "Mobile number must include country code with + prefix (e.g., +966501234567)"
          ]
        }
      }
    }
  }
  ```

  ```json Placement Not Found Error theme={null}
  {
    "error": "Placement not found",
    "error_code": "PLACEMENT_NOT_FOUND",
    "message": "No placement found with identifier: non-existent-placement"
  }
  ```
</ResponseExample>

## Usage

The Placements API can return either structured JSON data or HTML content directly, depending on your Accept header.

### Getting HTML Content Directly

To receive HTML content directly (for iframe or server-side rendering), set the Accept header:

```bash theme={null}
curl https://api.mazeedplus.com/select-placement \
  -H "x-publishable-api-key: pk_live_51H7..." \
  -H "Content-Type: application/json" \
  -H "Accept: text/html" \
  -d '{
    "identifier": "home",
    "attributes": {
      "userId": "user_123456789",
      "q": "كولومبي قهوه"
    }
  }'

# Returns HTML document directly:
# <!DOCTYPE html>
# <html>
#   <head><style>...</style></head>
#   <body>...</body>
# </html>
```

### Getting Structured JSON Data

For native mobile apps or custom rendering, request JSON (default):

```javascript theme={null}
const response = await fetch("https://api.mazeedplus.com/select-placement", {
  method: "POST",
  headers: {
    "x-publishable-api-key": "pk_live_51H7...",
    "Content-Type": "application/json",
    "Accept": "application/json"  // Optional, JSON is default
  },
  body: JSON.stringify({
    identifier: "home",
    attributes: {
      userId: "user_123456789",
      q: "كولومبي قهوه"
    }
  })
});

const placement = await response.json();
// Use placement.template_data for native rendering
```

### Native mobile integration

Use the structured data for native rendering:

```swift theme={null}
// iOS example
struct Product {
    let id: String
    let title: String
    let price: Price
    let imageUrl: String
    let url: String
}

// Parse collections and products
let collections = placement.data.entities.filter { $0.object == "collection" }
let products = placement.data.entities.filter { $0.object == "product" }

// Display featured collection
if let featured = collections.first(where: { $0.id == "col_featured" }) {
    let featuredProducts = featured.items.compactMap { item in
        products.first { $0.id == item.ref }
    }
    displayProductCollection(featuredProducts)
}
```
