Real Estate Listing Pipeline

Extract property data from documents, optimize photos, and generate listing cards for real estate platforms.

Who this is for

Real estate agencies and property platforms use this pipeline to create listings automatically. Extract property details from a listing document, optimize the property photo, and generate a professional listing card — all in three API calls.

# Step 1: Extract property data from listing document
curl -X POST https://api.iterationlayer.com/document-extraction/v1/extract \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "files": [
      {
        "type": "url",
        "name": "listing.pdf",
        "url": "https://example.com/properties/listing-2026.pdf"
      }
    ],
    "schema": {
      "fields": [
        { "name": "address", "type": "ADDRESS", "description": "Property address" },
        { "name": "listing_price", "type": "CURRENCY_AMOUNT", "description": "Listing price" },
        { "name": "bedrooms", "type": "INTEGER", "description": "Number of bedrooms" },
        { "name": "bathrooms", "type": "INTEGER", "description": "Number of bathrooms" }
      ]
    }
  }'

# The response JSON contains extracted property data.
# Use the property details for the listing card in Step 3.

# Step 2: Optimize the property photo (resize, enhance, sharpen, convert to JPEG)
TRANSFORM_RESULT=$(curl -s -X POST https://api.iterationlayer.com/image-transformation/v1/transform \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "file": {
      "type": "url",
      "name": "property-photo.jpg",
      "url": "https://example.com/properties/photo-exterior.jpg"
    },
    "operations": [
      { "type": "resize", "width_in_px": 1200, "height_in_px": 800, "fit": "cover" },
      { "type": "auto_contrast" },
      { "type": "sharpen", "sigma": 1.5 },
      { "type": "convert", "format": "jpeg", "quality": 90 }
    ]
  }')

OPTIMIZED_PHOTO_BASE64=$(echo "$TRANSFORM_RESULT" | jq -r '.data.buffer')

# Step 3: Generate a listing card with the optimized photo and property details
curl -X POST https://api.iterationlayer.com/image-generation/v1/generate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "dimensions": { "width": 1200, "height": 628 },
    "output_format": "png",
    "layers": [
      {
        "index": 0,
        "type": "solid-color-background",
        "hex_color": "#FFFFFF"
      },
      {
        "index": 1,
        "type": "static-image",
        "buffer": "<base64-encoded-optimized-property-photo>",
        "position": { "x": 0.0, "y": 0.0 },
        "dimensions": { "width": 1200, "height": 420 }
      },
      {
        "index": 2,
        "type": "rectangle",
        "hex_color": "#1B5E20",
        "position": { "x": 900.0, "y": 360.0 },
        "dimensions": { "width": 260, "height": 50 }
      },
      {
        "index": 3,
        "type": "text",
        "text": "$425,000",
        "font_name": "Roboto",
        "font_size_in_px": 28,
        "text_color": "#FFFFFF",
        "font_weight": "Bold",
        "text_align": "center",
        "position": { "x": 900.0, "y": 365.0 },
        "dimensions": { "width": 260, "height": 40 }
      },
      {
        "index": 4,
        "type": "text",
        "text": "742 Evergreen Terrace, Springfield",
        "font_name": "Inter",
        "font_size_in_px": 26,
        "text_color": "#1a1a1a",
        "font_weight": "Bold",
        "position": { "x": 40.0, "y": 445.0 },
        "dimensions": { "width": 800, "height": 40 }
      },
      {
        "index": 5,
        "type": "text",
        "text": "3 Bed · 2 Bath",
        "font_name": "Inter",
        "font_size_in_px": 20,
        "text_color": "#6B7280",
        "position": { "x": 40.0, "y": 500.0 },
        "dimensions": { "width": 400, "height": 30 }
      }
    ]
  }'
import { IterationLayer } from "iterationlayer";
const client = new IterationLayer({ apiKey: "YOUR_API_KEY" });

// Step 1: Extract property data from listing document
const propertyResult = await client.extract({
  files: [
    {
      type: "url",
      name: "listing.pdf",
      url: "https://example.com/properties/listing-2026.pdf",
    },
  ],
  schema: {
    fields: [
      { name: "address", type: "ADDRESS", description: "Property address" },
      { name: "listing_price", type: "CURRENCY_AMOUNT", description: "Listing price" },
      { name: "bedrooms", type: "INTEGER", description: "Number of bedrooms" },
      { name: "bathrooms", type: "INTEGER", description: "Number of bathrooms" },
    ],
  },
});

const property = propertyResult.results[0];

// Step 2: Optimize the property photo (resize, enhance, sharpen, convert to JPEG)
const transformResult = await client.transform({
  file: {
    type: "url",
    name: "property-photo.jpg",
    url: "https://example.com/properties/photo-exterior.jpg",
  },
  operations: [
    { type: "resize", width_in_px: 1200, height_in_px: 800, fit: "cover" },
    { type: "auto_contrast" },
    { type: "sharpen", sigma: 1.5 },
    { type: "convert", format: "jpeg", quality: 90 },
  ],
});

const optimizedPhotoBase64 = transformResult.data.buffer;

// Step 3: Generate a listing card with the optimized photo and property details
const cardResult = await client.generateImage({
  dimensions: { width_in_px: 1200, height_in_px: 628 },
  output_format: "png",
  layers: [
    {
      index: 0,
      type: "solid-color-background",
      hex_color: "#FFFFFF",
    },
    {
      index: 1,
      type: "static-image",
      buffer: optimizedPhotoBase64,
      position: { x_in_px: 0, y_in_px: 0 },
      dimensions: { width_in_px: 1200, height_in_px: 420 },
    },
    {
      index: 2,
      type: "rectangle",
      hex_color: "#1B5E20",
      position: { x_in_px: 900, y_in_px: 360 },
      dimensions: { width_in_px: 260, height_in_px: 50 },
    },
    {
      index: 3,
      type: "text",
      text: `${property.listing_price}`,
      font_name: "Roboto",
      font_size_in_px: 28,
      text_color: "#FFFFFF",
      font_weight: "Bold",
      text_align: "center",
      position: { x_in_px: 900, y_in_px: 365 },
      dimensions: { width_in_px: 260, height_in_px: 40 },
    },
    {
      index: 4,
      type: "text",
      text: property.address,
      font_name: "Inter",
      font_size_in_px: 26,
      text_color: "#1a1a1a",
      font_weight: "Bold",
      position: { x_in_px: 40, y_in_px: 445 },
      dimensions: { width_in_px: 800, height_in_px: 40 },
    },
    {
      index: 5,
      type: "text",
      text: `${property.bedrooms} Bed · ${property.bathrooms} Bath`,
      font_name: "Inter",
      font_size_in_px: 20,
      text_color: "#6B7280",
      position: { x_in_px: 40, y_in_px: 500 },
      dimensions: { width_in_px: 400, height_in_px: 30 },
    },
  ],
});

const listingCardBuffer = Buffer.from(cardResult.data.buffer, "base64");
import base64

from iterationlayer import IterationLayer
client = IterationLayer(api_key="YOUR_API_KEY")

# Step 1: Extract property data from listing document
property_result = client.extract(
    files=[
        {
            "type": "url",
            "name": "listing.pdf",
            "url": "https://example.com/properties/listing-2026.pdf",
        }
    ],
    schema={
        "fields": [
            {"name": "address", "type": "ADDRESS", "description": "Property address"},
            {"name": "listing_price", "type": "CURRENCY_AMOUNT", "description": "Listing price"},
            {"name": "bedrooms", "type": "INTEGER", "description": "Number of bedrooms"},
            {"name": "bathrooms", "type": "INTEGER", "description": "Number of bathrooms"},
        ]
    },
)

property_info = property_result["results"][0]

# Step 2: Optimize the property photo (resize, enhance, sharpen, convert to JPEG)
transform_result = client.transform(
    file={
        "type": "url",
        "name": "property-photo.jpg",
        "url": "https://example.com/properties/photo-exterior.jpg",
    },
    operations=[
        {"type": "resize", "width_in_px": 1200, "height_in_px": 800, "fit": "cover"},
        {"type": "auto_contrast"},
        {"type": "sharpen", "sigma": 1.5},
        {"type": "convert", "format": "jpeg", "quality": 90},
    ],
)

optimized_photo_base64 = transform_result["data"]["buffer"]

# Step 3: Generate a listing card with the optimized photo and property details
card_result = client.generate_image(
    dimensions={"width_in_px": 1200, "height_in_px": 628},
    output_format="png",
    layers=[
        {
            "index": 0,
            "type": "solid-color-background",
            "hex_color": "#FFFFFF",
        },
        {
            "index": 1,
            "type": "static-image",
            "buffer": optimized_photo_base64,
            "position": {"x_in_px": 0, "y_in_px": 0},
            "dimensions": {"width_in_px": 1200, "height_in_px": 420},
        },
        {
            "index": 2,
            "type": "rectangle",
            "hex_color": "#1B5E20",
            "position": {"x_in_px": 900, "y_in_px": 360},
            "dimensions": {"width_in_px": 260, "height_in_px": 50},
        },
        {
            "index": 3,
            "type": "text",
            "text": str(property_info["listing_price"]),
            "font_name": "Roboto",
            "font_size_in_px": 28,
            "text_color": "#FFFFFF",
            "font_weight": "Bold",
            "text_align": "center",
            "position": {"x_in_px": 900, "y_in_px": 365},
            "dimensions": {"width_in_px": 260, "height_in_px": 40},
        },
        {
            "index": 4,
            "type": "text",
            "text": property_info["address"],
            "font_name": "Inter",
            "font_size_in_px": 26,
            "text_color": "#1a1a1a",
            "font_weight": "Bold",
            "position": {"x_in_px": 40, "y_in_px": 445},
            "dimensions": {"width_in_px": 800, "height_in_px": 40},
        },
        {
            "index": 5,
            "type": "text",
            "text": f"{property_info['bedrooms']} Bed · {property_info['bathrooms']} Bath",
            "font_name": "Inter",
            "font_size_in_px": 20,
            "text_color": "#6B7280",
            "position": {"x_in_px": 40, "y_in_px": 500},
            "dimensions": {"width_in_px": 400, "height_in_px": 30},
        },
    ],
)

with open("listing-card.png", "wb") as f:
    f.write(base64.b64decode(card_result["data"]["buffer"]))
package main

import il "github.com/iterationlayer/sdk-go"

client := il.NewClient("YOUR_API_KEY")

// Step 1: Extract property data from listing document
propertyResult, err := client.Extract(il.ExtractRequest{
    Files: []il.FileInput{
        il.NewFileFromURL("listing.pdf", "https://example.com/properties/listing-2026.pdf"),
    },
    Schema: il.ExtractionSchema{
        "address":       il.NewAddressFieldConfig("address", "Property address"),
        "listing_price": il.NewCurrencyAmountFieldConfig("listing_price", "Listing price"),
        "bedrooms":      il.NewIntegerFieldConfig("bedrooms", "Number of bedrooms"),
        "bathrooms":     il.NewIntegerFieldConfig("bathrooms", "Number of bathrooms"),
    },
})

// Step 2: Optimize the property photo (resize, enhance, sharpen, convert to JPEG)
transformResult, err := client.Transform(il.TransformRequest{
    File: il.NewFileFromURL("property-photo.jpg", "https://example.com/properties/photo-exterior.jpg"),
    Operations: []il.TransformOperation{
        il.NewResizeOperation(1200, 800, "cover"),
        {Type: "auto_contrast"},
        il.NewSharpenOperation(1.5),
        il.NewConvertOperation("jpeg"),
    },
})

// Step 3: Generate a listing card with the optimized photo and property details
cardResult, err := client.GenerateImage(il.GenerateImageRequest{
    Dimensions:   il.Dimensions{WidthInPx: 1200, HeightInPx: 628},
    OutputFormat: "png",
    Layers: []il.Layer{
        il.NewSolidColorBackgroundLayer(0, "#FFFFFF"),
        il.NewStaticImageLayer(1, il.FileInput{Buffer: transformResult.Data.Buffer},
            il.Position{XInPx: 0, YInPx: 0},
            il.Dimensions{WidthInPx: 1200, HeightInPx: 420}),
        il.NewRectangleLayer(2, "#1B5E20",
            il.Position{XInPx: 900, YInPx: 360},
            il.Dimensions{WidthInPx: 260, HeightInPx: 50}),
        il.NewTextLayer(3, "$425,000", "Roboto", 28, "#FFFFFF",
            il.Position{XInPx: 900, YInPx: 365},
            il.Dimensions{WidthInPx: 260, HeightInPx: 40}),
        il.NewTextLayer(4, "742 Evergreen Terrace, Springfield", "Inter", 26, "#1a1a1a",
            il.Position{XInPx: 40, YInPx: 445},
            il.Dimensions{WidthInPx: 800, HeightInPx: 40}),
        il.NewTextLayer(5, "3 Bed \u00b7 2 Bath", "Inter", 20, "#6B7280",
            il.Position{XInPx: 40, YInPx: 500},
            il.Dimensions{WidthInPx: 400, HeightInPx: 30}),
    },
})

Related Recipes

Start building in minutes

Free trial credits included. No credit card required.