Skip to content

Unified API Worked Examples

A worked example for each common use case, so you can see a request and response close to what your own integration will send. Every example follows the same template:

  • Scenario: what's being reviewed and why.
  • Request: a complete, copy-pasteable payload.
  • Response: a representative result.
  • What to notice: the details that matter for your integration.

Two things to keep in mind while reading:

  1. All requests use the same envelope (environment, optional id, data) and go to POST /api/v1/review/{workflow_name}.
  2. The field names inside data, and the shape of metadata.result, are workflow-specific. These examples show typical shapes; we confirm the exact ones for your workflows during onboarding.

Content moderation (text + image)

Scenario: a piece of user-generated content, a product image plus its caption, is checked against a policy before it's published.

Request to POST /api/v1/review/image:

{
  "environment": "prod",
  "id": "listing-555",
  "data": {
    "context": "product-image",
    "content": {
      "text": { 
        "content":  "Genuine designer handbag, 90% off retail", 
        "fieldType":  "description"
      },
      "imageUrl": { "photoUrl": "https://cdn.example.com/img-1.png" }
    }
  }
}

Response:

{
  "messages": [],
  "id": "listing-555",
  "decisionId": null,
  "status": "success",
  "subjectId": null,
  "eventTime": "2024-01-01T00:00:00+00:00",
  "metadata": {
    "result": {
      "data": {
        "labels": [
          {
            "label": "Counterfeit",
            "assessment": "FLAGGED",
            "labelerOutput": {"label": "Counterfeit", "analysis": "...", "riskScore": 9}
          }
        ]
      }
    },
    "execution": {}
  }
}

What to notice:

  • content holds the modalities that the policy evaluates (text, imageUrl), keyed to the policy's configured input fields (content, fieldType, photoUrl); context tells the workflow which surface the content came from. Your workflow defines its own names.
  • The verdict is in metadata.result: the matched label, the assessment (CLEAR / FLAGGED), and a riskScore from 0 to 10 you can automate against.

Ad creative review

Scenario: an ad server submits a creative for policy review before it serves. You send the ad tag as-is; the workflow renders it, extracts the media the ad actually displays, and classifies that media against your ad policies.

Request to POST /api/v1/review/ad-creative-review:

{
  "environment": "prod",
  "id": "creative-ndqe9ray",
  "data": {
    "creativeId": "ndqe9ray",
    "adServerName": "gam",
    "creativeType": "video",
    "adTag": "<script src=\"https://ads.example.com/tag/ndqe9ray.js\"></script>",
    "imageUrl": null,
    "clickThroughUrl": "https://brand.example.com/spring-sale",
    "partnerName": "Acme DSP",
    "partnerId": "partner-042",
    "advertiserName": "Acme Shoes",
    "advertiserId": "adv-1234",
    "createdAt": "2026-01-05T09:30:00+00:00",
    "updatedAt": "2026-01-06T14:00:00+00:00"
  }
}
Field Required Description
creativeId yes Your identifier for the creative.
adServerName yes The ad server the creative comes from.
creativeType yes The creative format, e.g. display, video, native.
adTag yes The ad tag: an HTML snippet or a URL.
imageUrl yes (nullable) Direct URL to the creative's image, when you have one.
clickThroughUrl yes (nullable) The landing page the creative links to.
partnerName, partnerId, advertiserName, advertiserId, createdAt, updatedAt no Captured as subject details; useful for analytics and reporting.

How it runs: the workflow's first step renders the ad tag and extracts the actual creative media. Extraction is tuned for speed: when a video is available in multiple renditions, it loads a lower-resolution version rather than the full-quality file. The extracted media then goes to a standard policy step for classification.

Response:

{
  "messages": [],
  "id": "creative-ndqe9ray",
  "decisionId": null,
  "status": "success",
  "subjectId": "ndqe9ray",
  "eventTime": "2026-01-06T14:00:05+00:00",
  "metadata": {
    "result": {
      "data": {
        "labels": [
          {
            "label": "Prohibited Products",
            "assessment": "CLEAR",
            "labelerOutput": {"label": "Prohibited Products", "analysis": "...", "riskScore": 1}
          },
          {
            "label": "Sexually Suggestive",
            "assessment": "FLAGGED",
            "labelerOutput": {"label": "Sexually Suggestive", "analysis": "...", "riskScore": 8}
          }
        ]
      }
    },
    "execution": {}
  }
}

What to notice:

  • You don't extract media yourself. Send the tag (snippet or URL) and the workflow handles rendering and extraction.
  • imageUrl and clickThroughUrl are nullable: send null when you don't have them rather than omitting the fields.
  • The partner and advertiser fields aren't needed for the review itself, but including them makes decision history filterable by partner and advertiser later.

Account-level moderation & fraud detection

Scenario: a user is reported for spam. The workflow analyzes everything you know about the account, profile, activity, and history together, and returns an automated decision.

Request to POST /api/v1/review/account-review:

{
  "environment": "prod",
  "id": "report-123",
  "data": {
    "userId": "user-123",
    "eventTime": "2024-01-01T00:00:00+00:00",
    "triggerReason": "spam",
    "comments": "flagged for review",
    "account": {"email": "test@example.com", "signupCountry": "US", "accountAgeDays": 3},
    "profile": {"name": "Test User", "bio": "..."},
    "activity": {"messagesSent": 240, "reportsAgainst": 5}
  }
}

Response:

{
  "messages": [],
  "id": "report-123",
  "decisionId": null,
  "status": "success",
  "subjectId": "user-123",
  "eventTime": "2024-01-01T00:00:00+00:00",
  "metadata": {
    "result": {
      "decision": {
        "decisionType": {"value": "BAN", "name": "Ban"},
        "banReason": {"value": "SPAM", "name": "Spam"},
        "extra": {"score": 92}
      }
    },
    "execution": {}
  }
}

What to notice:

  • The subject details are free-form nested JSON. Send whatever signals you have; more signal means better analysis.
  • The verdict is a decision (APPROVE / SKIP / BAN) rather than per-policy labels. Act on APPROVE and BAN, and route SKIP to your moderators.

Marketplace listing review

Scenario: a seller publishes a listing. The workflow reviews the title, description, price, and all photos together as one entity, rather than checking each piece in isolation.

Request to POST /api/v1/review/listing-review:

{
  "environment": "prod",
  "id": "listing-88211",
  "data": {
    "listingId": "88211",
    "sellerId": "seller-431",
    "listing": {
      "title": "Designer handbag, brand new",
      "description": "100% authentic, ships fast from our warehouse.",
      "price": 79.99,
      "currency": "USD",
      "category": "bags"
    },
    "images": [
      "https://cdn.example.com/listings/88211/1.jpg",
      "https://cdn.example.com/listings/88211/2.jpg",
      "https://cdn.example.com/listings/88211/3.jpg"
    ]
  }
}

Response:

{
  "messages": [],
  "id": "listing-88211",
  "decisionId": null,
  "status": "success",
  "subjectId": "88211",
  "eventTime": "2024-01-01T00:00:00+00:00",
  "metadata": {
    "result": {
      "data": {
        "labels": [
          {
            "label": "Counterfeit",
            "assessment": "FLAGGED",
            "labelerOutput": {"label": "Counterfeit", "analysis": "...", "riskScore": 9}
          }
        ]
      }
    },
    "execution": {}
  }
}

What to notice:

  • images is a list: all three photos are evaluated together with the text, as one listing.
  • Cross-signal reasoning is the point: a low price plus "100% authentic" plus brand-name photos is a stronger counterfeit signal than any one field alone.

Multi-step pipeline: profile screening

Scenario: a new profile is screened cheaply on signup. The workflow checks the profile photo first, and only if it looks risky escalates the whole profile to a full account-level review. One call, one result.

Request to POST /api/v1/review/profile-screen:

{
  "environment": "prod",
  "id": "profile-check-42",
  "data": {
    "userId": "user-789",
    "eventTime": "2024-01-01T00:00:00+00:00",
    "profile": {
      "name": "...",
      "bio": "...",
      "photoUrl": "https://cdn.example.com/u/789/avatar.jpg"
    },
    "account": {"signupCountry": "US", "accountAgeDays": 1}
  }
}

Response:

{
  "messages": [],
  "id": "profile-check-42",
  "decisionId": null,
  "status": "success",
  "subjectId": "user-789",
  "eventTime": "2024-01-01T00:00:00+00:00",
  "metadata": {
    "result": {
      "decision": {"decision": "BAN", "reason": "Adult Content", "source": "aimod", "confidence": 88},
      "evidence": {"policyai": { }, "aimod": { }}
    },
    "execution": {}
  }
}

What to notice:

  • You send one snapshot; the workflow decides how far to take the review. Most profiles stop after the cheap photo screen.
  • The result carries both a compact decision you can act on directly and per-stage evidence for audit and debugging.
  • Latency varies by path: a clean profile returns in a couple of seconds, an escalated one takes as long as the deep review it triggered.