EnterRank
{ }API reference

API reference

A REST API over the same data the dashboard uses: reviews, grid scans, AI visibility probes and profile signals. JSON in, JSON out.

This deployment runs in demo mode. Every endpoint below is live and returns real JSON against a fixed sample dataset — copy any command and run it. Write methods validate your request and return 202 Accepted without persisting anything. Responses carry a "demo": true flag and an X-EnterRank-Mode: demo header.

Base URL

https://api.enterrank.io/v1

Rate limit

600 req / min

Format

JSON · UTF-8

Authentication

Server-to-server calls use an API key. Keys are created in Settings, shown once, and scoped to a single workspace.

X-API-Key: erk_live_your_key_here

Browser sessions

Authorization: Bearer <session_token>

List endpoints return a paginated envelope. Pass page and per_page; per_page is capped at 100.

GET https://api.enterrank.io/v1/reviews?page=2&per_page=25

{
  "data": [ ... ],
  "meta": {
    "current_page": 2,
    "per_page": 25,
    "total": 218,
    "last_page": 9
  }
}

Errors

400bad_requestMalformed query string.
401unauthenticatedMissing or invalid API key.
403forbiddenKey is not scoped to this location.
404not_foundNo resource matches that identifier.
422unprocessableValidation failed; see error.fields.
429rate_limitedRetry after the seconds given in Retry-After.
{
  "error": {
    "code": "unprocessable",
    "message": "No tracked keyword with id kw_99.",
    "fields": {
      "keyword_id": ["Must be one of: kw_01, kw_02, kw_03, kw_04, kw_05, kw_06"]
    }
  }
}

Reviews

GET/reviews

Lists reviews, newest first.

Query parameters

statusstringneeds_reply · drafted · answered · ignored
sentimentstringpositive · neutral · negative
ratinginteger1–5
pageintegerDefault 1
per_pageintegerDefault 25, max 100

Example request

curl "https://api.enterrank.io/v1/reviews?status=needs_reply&per_page=2" \
  -H "X-API-Key: erk_live_your_key_here"

Example response

{
  "data": [
    {
      "id": "rev_2f9a1",
      "author": "Marina Kovač",
      "rating": 2,
      "createdAt": "2026-07-27T16:52:00Z",
      "status": "needs_reply",
      "sentiment": "negative",
      "sentimentConfidence": 0.94,
      "intent": "wait_time",
      "topics": ["waiting time", "colour service", "pricing"]
    }
  ],
  "meta": { "current_page": 1, "per_page": 2, "total": 4, "last_page": 2 }
}
GET/reviews/{id}

Returns a single review with its reply, if one exists.

Example request

curl "https://api.enterrank.io/v1/reviews/rev_2f9a1" \
  -H "X-API-Key: erk_live_your_key_here"

Example response

{ "data": { "id": "rev_2f9a1", "author": "Marina Kovač", ... } }
POST/reviews/{id}/reply

Generates a reply draft in the workspace brand voice, optimised for the location's target keywords. Nothing is published.

Example request

curl -X POST "https://api.enterrank.io/v1/reviews/rev_2f9a1/reply" \
  -H "X-API-Key: erk_live_your_key_here"

Example response

{
  "data": {
    "review_id": "rev_2f9a1",
    "text": { "en": "Marina, you are right and we are sorry...", "hr": "..." },
    "keywords": ["Ilica hair salon", "colour appointment"],
    "seo_score": 87,
    "stages": [
      { "id": "analyze",  "duration_ms": 900 },
      { "id": "voice",    "duration_ms": 700 },
      { "id": "keywords", "duration_ms": 800 },
      { "id": "compose",  "duration_ms": 600 }
    ],
    "generated_at": "2026-07-28T07:00:00Z"
  }
}
PUT/reviews/{id}/reply

Publishes an approved reply to Google.

Example request

curl -X PUT "https://api.enterrank.io/v1/reviews/rev_2f9a1/reply" \
  -H "X-API-Key: erk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"text": "Marina, you are right and we are sorry..."}'

Example response

{
  "accepted": true,
  "applied": false,
  "message": "Publishing a reply to review rev_2f9a1 was accepted but not persisted — this deployment runs in demo mode."
}

Rankings

GET/keywords

Lists tracked search terms.

Example request

curl "https://api.enterrank.io/v1/keywords" \
  -H "X-API-Key: erk_live_your_key_here"

Example response

{
  "data": [
    { "id": "kw_02", "term": { "en": "balayage zagreb" }, "volume": 1300, "avgRank": 2.4, "delta": -0.8 }
  ],
  "meta": { "current_page": 1, "per_page": 25, "total": 6, "last_page": 1 }
}
GET/scans

Runs a geo-grid scan for one keyword and returns every sampled point. rank is null where the business does not appear.

Query parameters

keyword_idstringRequired in practice; defaults to the first tracked term
sizeintegerOdd number 5–13. Grid is size × size
spacing_metersinteger100–5000

Example request

curl "https://api.enterrank.io/v1/scans?keyword_id=kw_02&size=7&spacing_meters=500" \
  -H "X-API-Key: erk_live_your_key_here"

Example response

{
  "data": {
    "id": "scan_kw_02",
    "keywordId": "kw_02",
    "size": 7,
    "spacingMeters": 500,
    "ranAt": "2026-07-28T06:00:00Z",
    "points": [
      { "row": 0, "col": 0, "offsetX": -1500, "offsetY": -1500, "rank": 4, "topCompetitor": "Salon Adriana" }
    ],
    "avgRank": 2.4,
    "atrs": 97.6,
    "solv": 95.9
  },
  "history": [ { "date": "2026-07-28", "atrs": 41.7 } ]
}

AI visibility

GET/ai-visibility

Returns tracked prompts with each assistant's verdict, the competitors named instead, and the sources cited.

Query parameters

enginestringchatgpt · gemini · perplexity · ai_overviews

Example request

curl "https://api.enterrank.io/v1/ai-visibility?engine=chatgpt" \
  -H "X-API-Key: erk_live_your_key_here"

Example response

{
  "data": [
    {
      "id": "probe_01",
      "prompt": { "en": "best hair salon in central Zagreb" },
      "visibilityScore": 62,
      "delta": 14,
      "results": [
        {
          "engine": "chatgpt",
          "mentioned": true,
          "position": 2,
          "competitorsNamed": ["Salon Adriana", "Hair Lab Zagreb"],
          "citedSources": ["google.com/maps", "studiolucia.hr", "tripadvisor.com"],
          "checkedAt": "2026-07-28T05:00:00Z"
        }
      ]
    }
  ],
  "meta": { "current_page": 1, "per_page": 25, "total": 4, "last_page": 1 }
}

Presence

GET/presence/profile-score

Returns the weighted profile completeness score and the individual checks behind it.

Example request

curl "https://api.enterrank.io/v1/presence/profile-score" \
  -H "X-API-Key: erk_live_your_key_here"

Example response

{
  "data": {
    "location_id": "loc_8f21c",
    "score": 78,
    "checks": [
      { "id": "chk_03", "weight": 14, "passed": false,
        "label": { "en": "All services listed with prices" } }
    ]
  }
}
GET/presence/posts

Lists profile posts.

Query parameters

statusstringdraft · scheduled · published

Example request

curl "https://api.enterrank.io/v1/presence/posts?status=published" \
  -H "X-API-Key: erk_live_your_key_here"

Example response

{
  "data": [
    { "id": "post_03", "status": "published", "cta": "learn_more",
      "publishedAt": "2026-07-22T08:00:00Z", "metrics": { "views": 1284, "clicks": 96 } }
  ],
  "meta": { "current_page": 1, "per_page": 25, "total": 3, "last_page": 1 }
}
GET/presence/questions

Lists profile questions.

Query parameters

unansweredbooleantrue returns only unanswered questions

Example request

curl "https://api.enterrank.io/v1/presence/questions?unanswered=true" \
  -H "X-API-Key: erk_live_your_key_here"

Example response

{
  "data": [
    { "id": "qst_01", "author": "Marta B.", "views": 340,
      "question": { "en": "Do you do keratin treatments and how much do they cost?" } }
  ],
  "meta": { "current_page": 1, "per_page": 25, "total": 4, "last_page": 1 }
}

Workspace

GET/overview

Returns the dashboard metrics, including weekly series.

Example request

curl "https://api.enterrank.io/v1/overview" \
  -H "X-API-Key: erk_live_your_key_here"

Example response

{
  "data": {
    "reviewsAwaitingReply": 4,
    "medianResponseHours": 9,
    "rating": 4.6,
    "avgRank": 4.2,
    "aiVisibilityScore": 47,
    "profileScore": 78
  }
}
GET/locations

Lists locations connected to the workspace.

Example request

curl "https://api.enterrank.io/v1/locations" \
  -H "X-API-Key: erk_live_your_key_here"

Example response

{
  "data": [
    { "id": "loc_8f21c", "name": "Studio Lucia", "city": "Zagreb",
      "gbpLocationId": "locations/4192837465102938471", "rating": 4.6, "reviewCount": 218 }
  ],
  "meta": { "current_page": 1, "per_page": 25, "total": 1, "last_page": 1 }
}
GET/competitors

Lists the tracked local competitor set.

Example request

curl "https://api.enterrank.io/v1/competitors" \
  -H "X-API-Key: erk_live_your_key_here"

Example response

{
  "data": [
    { "id": "cmp_01", "name": "Salon Adriana", "rating": 4.8, "reviewCount": 412,
      "avgRank": 1.9, "aiVisibility": 71, "distanceMeters": 380 }
  ],
  "meta": { "current_page": 1, "per_page": 25, "total": 5, "last_page": 1 }
}
POST/contact

Submits a quote enquiry. Pricing is scoped per workspace rather than published, so this is how a quote is requested.

Example request

curl -X POST "https://api.enterrank.io/v1/contact" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Lucia Marić",
    "email": "lucia@studiolucia.hr",
    "business": "Studio Lucia",
    "city": "Zagreb",
    "locations": "1"
  }'

Example response

{
  "accepted": true,
  "applied": false,
  "message": "Your enquiry was accepted but not persisted — this deployment runs in demo mode."
}

Webhooks

review.createdreview.repliedscan.completedai_visibility.changedprofile.check_failed

Events are delivered as POST requests signed with HMAC-SHA256 in the X-EnterRank-Signature header. Respond 2xx within 5 seconds; failures retry with exponential backoff for 24 hours.

POST https://your-server.example/hooks/enterrank
X-EnterRank-Signature: sha256=...
Content-Type: application/json

{
  "event": "review.created",
  "created_at": "2026-07-27T16:52:04Z",
  "data": {
    "review_id": "rev_2f9a1",
    "location_id": "loc_8f21c",
    "rating": 2,
    "sentiment": "negative",
    "intent": "wait_time"
  }
}