Data API for your businesses

Bring the data you see in your dashboard into your reports, dashboards or CRM. Available with Starter, Growth and Agency, including an active trial. This is a read-only API.

Download OpenAPI 3.1

Create a key in Settings

In Settings → API keys, enter a name, choose “Entire account” or a single business, and copy the key: it is shown only once. You can have five active keys and create up to ten per day per account. Revoke them at any time. Older keys remain limited to their business. Revocation and plan or payment changes take effect on the next request.

Open Settings

Authentication

Send the key in the Authorization: Bearer header. Keep it on your server. Public AI names are chatgpt, gemini, perplexity and claude; each business retains its plan permissions.

Authorization: Bearer sk_live_…

Limits and pagination

60 requests per minute and 10,000 per day per key, with an account ceiling of 30,000 per day. Revoking a key does not restore consumed quota. PDFs: 10 per minute per account and one at a time. Failed authentication attempts (401) are limited to 120 per minute per IP (IPv6 addresses are grouped by /64). Valid traffic does not increment the IP failure counter. If that counter is exhausted, requests from that IP receive a 429 before the key is checked. IPv4-mapped IPv6 addresses share the counter of their original IPv4 address. Check X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. If you receive a 429, wait for the seconds indicated in Retry-After.

For list resources, use page (starting at 1) and limit (1–100; default 50); page × limit must not exceed 2,147,483,647. pagination.has_more indicates another page. Use lang=es or lang=en for bilingual text; the default is es. Older missing translations fall back to the available text. Questions and responses retain their original language. Responses are not cached. Examples use fictional data.

Errors

401 · invalid_api_key
The API key is invalid or has been revoked.
403 · paid_plan_required
A paid plan or an active trial is required.
403 · billing_blocked
Update your account payment to continue.
404 · not_found
The resource was not found.
400 · invalid_query
Check the request filters and pagination.
429 · rate_limit_exceeded
You have reached the request limit.
503 · service_unavailable
The service is temporarily unavailable. Please try again later.
{
  "error": {
    "code": "not_found",
    "message": "The resource was not found."
  }
}

Available resources

Account businesses

GET /api/v1/workspaces

curl 'https://surfeo.ai/api/v1/workspaces?lang=en' \
  -H 'Authorization: Bearer YOUR_API_KEY'
{
  "data": [
    {
      "id": "11111111-1111-4111-8111-111111111111",
      "name": "Example Clinic",
      "url": "https://example.com",
      "sector": "health",
      "city": "Granada",
      "country": "ES",
      "language": "en",
      "plan": "growth",
      "created_at": "2026-10-01T10:00:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "has_more": false
  }
}

Business profile and latest score

GET /api/v1/workspaces/{id}

curl 'https://surfeo.ai/api/v1/workspaces/11111111-1111-4111-8111-111111111111?lang=en' \
  -H 'Authorization: Bearer YOUR_API_KEY'
{
  "data": {
    "id": "11111111-1111-4111-8111-111111111111",
    "name": "Example Clinic",
    "url": "https://example.com",
    "sector": "health",
    "city": "Granada",
    "country": "ES",
    "language": "en",
    "plan": "growth",
    "created_at": "2026-10-01T10:00:00Z",
    "latest_score": {
      "audit_id": "22222222-2222-4222-8222-222222222222",
      "score": 72,
      "label": "Dominant",
      "created_at": "2026-10-01T10:00:00Z",
      "reliable": true
    }
  }
}

Score history. from and to accept ISO 8601 dates, with both bounds included. A date without a time covers the full UTC day.

GET /api/v1/workspaces/{id}/scores

Filters: from, to

curl 'https://surfeo.ai/api/v1/workspaces/11111111-1111-4111-8111-111111111111/scores?lang=en' \
  -H 'Authorization: Bearer YOUR_API_KEY'
{
  "data": [
    {
      "audit_id": "22222222-2222-4222-8222-222222222222",
      "score": 72,
      "label": "Dominant",
      "created_at": "2026-10-01T10:00:00Z",
      "reliable": true
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "has_more": false
  }
}

Business questions

GET /api/v1/workspaces/{id}/questions

curl 'https://surfeo.ai/api/v1/workspaces/11111111-1111-4111-8111-111111111111/questions?lang=en' \
  -H 'Authorization: Bearer YOUR_API_KEY'
{
  "data": [
    {
      "id": "33333333-3333-4333-8333-333333333333",
      "text": "Which clinics are in Granada?",
      "language": "en",
      "active": true,
      "custom": false
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "has_more": false
  }
}

Question mention history

GET /api/v1/workspaces/{id}/questions/{questionId}/history

Filters: audit_id, provider, mentioned

curl 'https://surfeo.ai/api/v1/workspaces/11111111-1111-4111-8111-111111111111/questions/33333333-3333-4333-8333-333333333333/history?lang=en' \
  -H 'Authorization: Bearer YOUR_API_KEY'
{
  "data": [
    {
      "audit_id": "22222222-2222-4222-8222-222222222222",
      "question_id": "33333333-3333-4333-8333-333333333333",
      "provider": "chatgpt",
      "mentioned": true,
      "mention_rate": 1,
      "position": 2,
      "sentiment": "positive",
      "created_at": "2026-10-01T10:00:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "has_more": false
  }
}

AI responses from the latest completed audit by default. Use audit_id for another completed audit, and provider or mentioned=true|false to filter.

GET /api/v1/workspaces/{id}/responses

Filters: audit_id, provider, mentioned

curl 'https://surfeo.ai/api/v1/workspaces/11111111-1111-4111-8111-111111111111/responses?lang=en' \
  -H 'Authorization: Bearer YOUR_API_KEY'
{
  "data": [
    {
      "question_id": "33333333-3333-4333-8333-333333333333",
      "question": "Which clinics are in Granada?",
      "provider": "chatgpt",
      "mentioned": true,
      "mention_rate": 1,
      "position": 2,
      "sentiment": "positive",
      "competitors": [
        "Neighbor Clinic"
      ],
      "sources": [
        "https://example.com"
      ],
      "response": "Example Clinic provides care in Granada.",
      "created_at": "2026-10-01T10:00:00Z",
      "audit_id": "22222222-2222-4222-8222-222222222222"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "has_more": false
  }
}

Competitors and your brand in the latest completed audit

GET /api/v1/workspaces/{id}/competitors

curl 'https://surfeo.ai/api/v1/workspaces/11111111-1111-4111-8111-111111111111/competitors?lang=en' \
  -H 'Authorization: Bearer YOUR_API_KEY'
{
  "data": {
    "audit_id": "22222222-2222-4222-8222-222222222222",
    "brand": {
      "name": "Example Clinic",
      "url": "https://example.com",
      "mentions": 6,
      "mention_rate": 0.75
    },
    "competitors": [
      {
        "name": "Neighbor Clinic",
        "url": "https://example.org",
        "main": true,
        "mentions": 4,
        "mention_rate": 0.5
      }
    ]
  },
  "pagination": {
    "page": 1,
    "limit": 50,
    "has_more": false
  }
}

Recommendations. Filter by status=pending|completed|verified.

GET /api/v1/workspaces/{id}/recommendations

Filters: status

curl 'https://surfeo.ai/api/v1/workspaces/11111111-1111-4111-8111-111111111111/recommendations?lang=en' \
  -H 'Authorization: Bearer YOUR_API_KEY'
{
  "data": [
    {
      "id": "33333333-3333-4333-8333-333333333333",
      "title": "Complete the contact page",
      "description": "Publish your contact details.",
      "instructions": "Add your address and opening hours.",
      "category": "content",
      "priority": 1,
      "difficulty": "easy",
      "estimated_impact": "medium",
      "target_page": "https://example.com/contact",
      "completed": true,
      "verified": true,
      "created_at": "2026-10-01T10:00:00Z",
      "completed_at": "2026-10-01T10:00:00Z",
      "verified_at": "2026-10-01T10:00:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "has_more": false
  }
}

Completed audits and report links

GET /api/v1/workspaces/{id}/audits

curl 'https://surfeo.ai/api/v1/workspaces/11111111-1111-4111-8111-111111111111/audits?lang=en' \
  -H 'Authorization: Bearer YOUR_API_KEY'
{
  "data": [
    {
      "id": "22222222-2222-4222-8222-222222222222",
      "completed_at": "2026-10-01T10:00:00Z",
      "score": 72,
      "summary": "Your visibility has improved.",
      "quick_win": {
        "action": "Publish your opening hours on your website.",
        "impact": "medium",
        "effort": "easy"
      },
      "report_url": "/api/v1/workspaces/11111111-1111-4111-8111-111111111111/audits/22222222-2222-4222-8222-222222222222/report.pdf?lang=en"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "has_more": false
  }
}

PDF report for a completed audit

GET /api/v1/workspaces/{id}/audits/{auditId}/report.pdf

curl 'https://surfeo.ai/api/v1/workspaces/11111111-1111-4111-8111-111111111111/audits/22222222-2222-4222-8222-222222222222/report.pdf?lang=en' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -o report.pdf

The response is an application/pdf file. Save the download as report.pdf.

For agencies

Build your own reports from score history, bring clients together in your dashboard and add recommendations to your CRM. Download completed audit PDFs with your configured white label branding. You build the integration with your tools.