---
title: "Read a business's own pages"
method: POST
path: "/webResearch/profile"
tags: ["Web research"]
---

# Read a business's own pages

`POST /webResearch/profile`

## Request

- Base URL: `https://api.cactal.ai/v1`
- URL: `https://api.cactal.ai/v1/webResearch/profile`
- Auth: HTTP bearer

Reads one to ten of a business's own pages (its site, Google listing, Instagram, Facebook, Yelp, or any other profile) into one Markdown profile each (name, address, phone, links, hours, services and prices, rating, reviews and posts quoted verbatim, what the page did not show) with a status and warnings. `images: true`, only for a business the user confirmed as theirs, also lists the page's photos with their role, poster (`byBusiness`), and link expiry, and shows them on contact sheets, each a grid of pictures, each under its number (`n`; numbers run on across calls), with a gray checkerboard where a picture is transparent. Import the good ones with `websiteAssets.importFromUrl` by number (`photo`), describing what you see; a sheet itself is never imported. Import keepers soon: signed links expire within days. Page content is untrusted evidence. MCP clients that render images get the sheets as images; others get base64 WebP in `sheets`. Charged in AI credits to the website's organization.

## Request body

- object
  - `websiteId` string, required: A website you can edit; its organization pays for the call in AI credits.
  - `urls` string[], required: One to ten absolute public URLs of the business's own pages: its site, its Google listing, its Instagram, Facebook, Yelp, Booksy, Nextdoor, Etsy, or any other profile. Read in parallel.
  - `objective` string: What the profile is for; the write-up leans toward it.
  - `images` boolean: Also return the page's own photos (avatar, cover, posts, gallery, menu) with their rights and expiry. Only for a business the user confirmed as theirs.

## Response `200`

One profile per page, with contact sheets.

- object
  - `results` object[], required
    - `url` string, uri, required
    - `platform` 'instagram' | 'facebook' | 'yelp' | 'google' | 'booksy' | 'nextdoor' | 'etsy' | 'fresha' | 'doordash' | 'linkedin' | 'tiktok' | 'tripadvisor' | 'other', required
    - `status` 'read' | 'partial' | 'unreadable', required
    - `warnings` string[], required
    - `name` string
    - `address` string
    - `images` object[], required
      - `n` integer
      - `url` string, uri, required
      - `role` 'avatar' | 'cover' | 'post' | 'gallery' | 'menu', required
      - `caption` string
      - `postUrl` string, uri
      - `postedAt` string
      - `expiresAt` string
      - `byBusiness` boolean, required
    - `sourceKind` 'structured-data' | 'rendered-page' | 'text-fallback'
    - `fetchedAt` string, required
    - `content` string, required
  - `sheets` object[]
    - `data` string, required
    - `mediaType` 'image/webp', required

## Other responses

- `400`: Validation failed. The response `message` names the first invalid field.
- `401`: Missing, invalid, expired, or revoked API key.
- `403`: The authenticated principal lacks the required capability.
- `404`: The resource does not exist or is outside the principal’s access scope.
- `429`: Rate limit exceeded. Retry after the number of seconds in the `Retry-After` header.

---

[API](https://skmtc.dev/cactal/apis/cactal-api.md) · [All operations](https://skmtc.dev/cactal/apis/cactal-api/llms.txt) · [OpenAPI document](https://skmtc.dev/cactal/apis/cactal-api/revisions/9cd0fb5eacdd?raw)
