Agent Workflow

This guide walks through the canonical workflow for an AI agent automating Google review management on behalf of a business owner. Each step shows both the CLI command and the equivalent raw HTTP request.


GET/v1/contacts?email=

Step 1 — Find or create a contact

Before enrolling a customer, check if they already exist using an email lookup. If they don't exist, create them. This prevents duplicate contacts.

Query parameters

  • Name
    email
    Type
    string
    Description

    Filter contacts by exact email address. Returns an empty list if no match is found.

Find by email

curl -G https://api.reviewrover.co/api/v1/contacts \
  -H "Authorization: Bearer {token}" \
  --data-urlencode "[email protected]"

Response

{
  "has_more": false,
  "data": [
    {
      "id": "cont_KYdl3lftgZXGRbxqoj",
      "email": "[email protected]",
      "first_name": "John",
      "last_name": "Smith",
      "phone": "555-1234",
      "created_at": "2025-03-01T10:00:00Z",
      "updated_at": "2025-03-01T10:00:00Z"
    }
  ]
}

If the contact doesn't exist, create them with POST /v1/contacts.

Required attributes

  • Name
    email
    Type
    string
    Description

    The contact's email address.

Optional attributes

  • Name
    first_name
    Type
    string
    Description

    Contact's first name.

  • Name
    last_name
    Type
    string
    Description

    Contact's last name.

  • Name
    phone
    Type
    string
    Description

    Contact's phone number (used for SMS campaigns).

Create contact

POST
/v1/contacts
curl https://api.reviewrover.co/api/v1/contacts \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","first_name":"John","last_name":"Smith","phone":"555-1234"}'

Response

{
  "id": "cont_KYdl3lftgZXGRbxqoj",
  "email": "[email protected]",
  "first_name": "John",
  "last_name": "Smith",
  "phone": "555-1234",
  "created_at": "2025-03-01T10:00:00Z",
  "updated_at": "2025-03-01T10:00:00Z"
}

GET/v1/campaigns

Step 2 — Pick a campaign

List available campaigns to find the right one for this contact. Campaigns define the message sequence (email/SMS) and the minimum star rating threshold.

List campaigns

GET
/v1/campaigns
curl https://api.reviewrover.co/api/v1/campaigns \
  -H "Authorization: Bearer {token}"

Response

{
  "has_more": false,
  "data": [
    {
      "id": "camp_AbCdEfGhIjKlMn",
      "name": "Post-Service Review Request",
      "active": true,
      "minimum_star_rating": 4,
      "created_at": "2025-01-15T08:00:00Z"
    }
  ]
}

POST/v1/enrollments

Step 3 — Enroll the contact

Enrolling a contact triggers the campaign's message sequence immediately. The enrollment tracks progress through the sequence and marks itself completed once the contact submits a review.

Required attributes

  • Name
    contact_id
    Type
    string
    Description

    The ID of the contact to enroll.

  • Name
    campaign_id
    Type
    string
    Description

    The ID of the campaign to enroll them in.

Enroll contact

POST
/v1/enrollments
curl https://api.reviewrover.co/api/v1/enrollments \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"contact_id":"cont_KYdl3lftgZXGRbxqoj","campaign_id":"camp_AbCdEfGhIjKlMn"}'

Response

{
  "id": "enr_XxYyZz123456",
  "contact_id": "cont_KYdl3lftgZXGRbxqoj",
  "campaign_id": "camp_AbCdEfGhIjKlMn",
  "completed": false,
  "created_at": "2025-03-17T12:00:00Z"
}

GET/v1/metrics/unreplied_reviews

Step 4 — Monitor the review queue

Poll this endpoint to check for new reviews that need a reply. It returns a structured summary optimized for agent use, including a per-location breakdown.

To avoid polling, register a webhook for the review.created event (see Step 6).

Unreplied reviews

GET
/v1/metrics/unreplied_reviews
curl https://api.reviewrover.co/api/v1/metrics/unreplied_reviews \
  -H "Authorization: Bearer {token}"

Response

{
  "count": 3,
  "reviews": [
    {
      "id": "rev_Aa1Bb2Cc3Dd4Ee",
      "rating": 5,
      "author": "Jane D.",
      "snippet": "Great service, highly recommend!",
      "received_at": "2025-03-16T09:30:00Z"
    }
  ],
  "locations": [
    { "name": "Austin", "count": 2 },
    { "name": "Dallas", "count": 1 }
  ]
}

POST/v1/reviews/:id/reply

Step 5 — Draft and post a reply

Generate an AI-drafted reply first, then review and post it. The generate endpoint returns a suggested reply without saving it. The POST /reply endpoint saves and (if configured) posts it to Google.

Generate draft

POST
/v1/reviews/rev_xxx/reply/generate
curl -X POST \
  https://api.reviewrover.co/api/v1/reviews/rev_Aa1Bb2Cc3Dd4Ee/reply/generate \
  -H "Authorization: Bearer {token}"

Draft response

{
  "draft": "Thank you so much for the kind words, Jane! We're thrilled to hear you had a great experience and we look forward to serving you again."
}

Once the draft looks good, save it as the official reply.

Required attributes

  • Name
    body
    Type
    string
    Description

    The reply text to post.

Post reply

POST
/v1/reviews/rev_xxx/reply
curl -X POST \
  https://api.reviewrover.co/api/v1/reviews/rev_Aa1Bb2Cc3Dd4Ee/reply \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"body":"Thank you so much for the kind words, Jane!"}'

Response

{
  "id": "rpl_MnOpQrSt123",
  "review_id": "rev_Aa1Bb2Cc3Dd4Ee",
  "body": "Thank you so much for the kind words, Jane!",
  "created_at": "2025-03-17T13:00:00Z"
}

POST/v1/webhook_subscriptions

Step 6 — Register a webhook (optional)

Instead of polling for new reviews, register a webhook URL. Review Rover will POST to your URL whenever a review.created or enrollment.completed event fires.

All webhook payloads include an X-ReviewRover-Signature: sha256=<hmac> header for verification.

Required attributes

  • Name
    url
    Type
    string
    Description

    The HTTPS URL to deliver events to.

  • Name
    event_types
    Type
    array
    Description

    Events to subscribe to. Supported: review.created, enrollment.completed.

Register webhook

POST
/v1/webhook_subscriptions
curl https://api.reviewrover.co/api/v1/webhook_subscriptions \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://myagent.com/hook","event_types":["review.created"]}'

Response

{
  "id": "whs_Uv1Wx2Yz3Ab4",
  "url": "https://myagent.com/hook",
  "event_types": ["review.created"],
  "active": true,
  "created_at": "2025-03-17T14:00:00Z"
}

Verify signature

When your endpoint receives a webhook, verify it came from Review Rover:

Verify webhook signature

const crypto = require('crypto')

function verifySignature(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex')
  return `sha256=${expected}` === signature
}

// In your handler:
const sig = req.headers['x-reviewrover-signature']
if (!verifySignature(req.rawBody, sig, process.env.WEBHOOK_SECRET)) {
  return res.status(401).send('Invalid signature')
}

GET/v1/metrics/review_velocity

Review velocity report

Use this endpoint to report review activity back to the business owner. Returns rolling counts and average ratings for the last 7 and 30 days.

Review velocity

GET
/v1/metrics/review_velocity
curl https://api.reviewrover.co/api/v1/metrics/review_velocity \
  -H "Authorization: Bearer {token}"

Response

{
  "last_7_days": {
    "count": 8,
    "avg_rating": 4.6
  },
  "last_30_days": {
    "count": 34,
    "avg_rating": 4.4
  }
}