Developers

OneTouchReview API for developers

Send review requests from your own software, and read your Google reviews, reviews from other sites, private feedback and stats. Every answer is JSON. Base URL: https://api.onetouchreview.com/api/v1

API access is part of Pro. Keys work while your account is on Pro (or the Pro trial). See pricing

Download the OpenAPI specEndpointsWebhooks

Sign in with an API key

Make a key in the OneTouchReview app under Settings → API keys & webhooks. The key starts with rev_ and is shown once. Send it in every call:

Authorization: Bearer rev_YOUR_API_KEY

Signed URL (no header)

For tools that can only post to a URL, each key also has a secret URL ending in whk_…: POST https://api.onetouchreview.com/api/v1/hooks/requests/whk_YOUR_URL_TOKEN. Treat it like a password.

Signing requests (optional)

A key can require signed requests. Add the header X-Rev-Signature: t={unix seconds},v1={hex HMAC-SHA256(signing secret, "{t}.{raw body}")}. The time must be within 5 minutes of ours and each signature is accepted once. A wrong signature is a 401 INVALID_SIGNATURE.

const body = JSON.stringify({ name: 'Jane Doe', phone: '+15555550123' })
const t = Math.floor(Date.now() / 1000)
const v1 = crypto.createHmac('sha256', signingSecret).update(`${t}.${body}`).digest('hex')
// send the same body, with the header  X-Rev-Signature: t=${t},v1=${v1}

Read-only and full-access keys

  • Full access: every endpoint, including sending review requests.
  • Read only: every GET and the Zapier subscriptions, but not sending review requests. A read-only key on POST /hooks/requests gets a 403:
{
  "error": {
    "code": "API_KEY_READ_ONLY",
    "message": "This key can only read. Use a full-access key to send review requests."
  }
}

You choose when you make the key; to change it, make a new key.

Endpoints

Customer phone numbers and emails are never sent back in review request, review or stats answers. Lists with next_cursor page with ?cursor=.

Review requests

GET/hooks/requests

List review requests

Review requests (follow-ups included), newest first, 50 a page.

Any key (read-only or full)

location_id(query)

Only this location (from GET /hooks/locations). Not one of yours → 404 LOCATION_NOT_FOUND.

status(query)

Only requests in this status.

from(query)

Only requests made on or after this day (UTC, YYYY-MM-DD).

to(query)

Only requests made on or before this day (UTC, YYYY-MM-DD).

cursor(query)

The next_cursor of the previous page.

Example call

curl "https://api.onetouchreview.com/api/v1/hooks/requests" \
  -H "Authorization: Bearer rev_YOUR_API_KEY" \
  -H "Accept: application/json"

Answer (200)

{
  "requests": [
    {
      "id": 9123,
      "status": "delivered",
      "channel": "sms",
      "location_id": 12,
      "customer": {
        "id": 5531,
        "name": "Nina Patel"
      },
      "sent_at": "2026-10-12T15:02:11.000000Z",
      "delivered_at": "2026-10-12T15:02:14.000000Z",
      "clicked_at": "2026-10-12T16:40:03.000000Z",
      "created_at": "2026-10-12T15:02:10.000000Z"
    }
  ],
  "next_cursor": "9123"
}
Error answers

401 The key is missing, wrong or revoked, or the signature is wrong.

{
  "error": {
    "code": "INVALID_API_KEY",
    "message": "The API key is missing, wrong or revoked."
  }
}

403 The plan doesn't include the API (Pro), or the account is suspended.

{
  "error": {
    "code": "PLAN_REQUIRED",
    "message": "The API is part of Pro. Upgrade to use it."
  }
}

404 location_id is not one of your locations.

{
  "error": {
    "code": "LOCATION_NOT_FOUND",
    "message": "Location not found."
  }
}

422 A parameter is not valid.

{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "The selected status is invalid.",
    "details": {
      "status": [
        "The selected status is invalid."
      ]
    }
  }
}

429 More than 120 calls this minute. Wait Retry-After seconds.

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many calls. Wait 42 seconds and try again."
  }
}

POST/hooks/requests

Send a review request

Adds the client (found by phone, else by email when there is no phone) and sends them a review request. Sending the same external_id again returns the first request and sends nothing (duplicate: true, 200). Senders may use their own field names: first_name + last_name → name; mobile, mobile_phone, cell, phone_number → phone; email_address → email; id, job_id, case_id, matter_id → external_id. Ours win when both are sent.

Add "test": true to run every check without keeping or sending anything.

Needs a full-access key. Every client gets the same request, and only clients who agreed to receive texts may be sent by text.

Full-access key only

Example call

curl -X POST "https://api.onetouchreview.com/api/v1/hooks/requests" \
  -H "Authorization: Bearer rev_YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name":"Nina Patel","phone":"(512) 555-0123","external_id":"case-1001","location_id":12,"staff_name":"Maria Gomez"}'

Answer (201)

{
  "id": 9125,
  "status": "queued",
  "sends_at": "2026-10-13T15:00:00.000000Z",
  "customer_id": 5531,
  "duplicate": false,
  "warnings": []
}
Error answers

401 The key is missing, wrong or revoked, or the signature is wrong.

{
  "error": {
    "code": "INVALID_API_KEY",
    "message": "The API key is missing, wrong or revoked."
  }
}

402 The account has no active subscription.

{
  "error": {
    "code": "SUBSCRIPTION_REQUIRED",
    "message": "A valid subscription is required to continue."
  }
}

403 A read-only key, the plan doesn't include the API (Pro), or the account is suspended.

{
  "error": {
    "code": "API_KEY_READ_ONLY",
    "message": "This key can only read. Use a full-access key to send review requests."
  }
}

404 location_id is not one of your locations.

{
  "error": {
    "code": "LOCATION_NOT_FOUND",
    "message": "Location not found."
  }
}

422 Not valid (VALIDATION_FAILED), or not sent, with the reason: RECENTLY_REQUESTED, CUSTOMER_OPTED_OUT, NO_CONSENT, NO_CHANNEL, QUOTA_EXHAUSTED, SMS_NOT_REGISTERED, LOCATION_PAUSED, NO_REVIEW_LINK, …

{
  "error": {
    "code": "RECENTLY_REQUESTED",
    "message": "Asked for a review recently. You can ask again on Jan 2, 2027."
  }
}

429 More than 120 calls this minute. Wait Retry-After seconds.

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many calls. Wait 42 seconds and try again."
  }
}

POST/hooks/requests/{urlToken}

Send a review request (secret URL)

The same as POST /hooks/requests, signed in by the key's secret URL instead of the Authorization header — for senders that can't set headers. The URL is shown once when the key is made; make a new one in the app if it leaks. Needs a full-access key.

Full-access key onlySigned URL, no header

urlToken(path, required)

The key's secret URL token (whk_…).

Example call

curl -X POST "https://api.onetouchreview.com/api/v1/hooks/requests/whk_YOUR_URL_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name":"Nina Patel","phone":"(512) 555-0123","external_id":"case-1001","location_id":12,"staff_name":"Maria Gomez"}'

Answer (201)

{
  "id": 9125,
  "status": "queued",
  "sends_at": "2026-10-13T15:00:00.000000Z",
  "customer_id": 5531,
  "duplicate": false,
  "warnings": []
}
Error answers

401 The key is missing, wrong or revoked, or the signature is wrong.

{
  "error": {
    "code": "INVALID_API_KEY",
    "message": "The API key is missing, wrong or revoked."
  }
}

402 The account has no active subscription.

{
  "error": {
    "code": "SUBSCRIPTION_REQUIRED",
    "message": "A valid subscription is required to continue."
  }
}

403 A read-only key, the plan doesn't include the API (Pro), or the account is suspended.

{
  "error": {
    "code": "API_KEY_READ_ONLY",
    "message": "This key can only read. Use a full-access key to send review requests."
  }
}

404 location_id is not one of your locations.

{
  "error": {
    "code": "LOCATION_NOT_FOUND",
    "message": "Location not found."
  }
}

422 Not valid (VALIDATION_FAILED), or not sent, with the reason: RECENTLY_REQUESTED, CUSTOMER_OPTED_OUT, NO_CONSENT, NO_CHANNEL, QUOTA_EXHAUSTED, SMS_NOT_REGISTERED, LOCATION_PAUSED, NO_REVIEW_LINK, …

{
  "error": {
    "code": "RECENTLY_REQUESTED",
    "message": "Asked for a review recently. You can ask again on Jan 2, 2027."
  }
}

429 More than 120 calls this minute. Wait Retry-After seconds.

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many calls. Wait 42 seconds and try again."
  }
}

GET/hooks/requests/{id}

Get one review request

One request, in the list's shape, plus not_sent_reason when it didn't go (failed, cancelled or expired; otherwise null). Another business's request is 404.

Any key (read-only or full)

id(path, required)

The review request id.

Example call

curl "https://api.onetouchreview.com/api/v1/hooks/requests/12" \
  -H "Authorization: Bearer rev_YOUR_API_KEY" \
  -H "Accept: application/json"

Answer (200)

{
  "id": 9124,
  "status": "failed",
  "channel": "sms",
  "location_id": 12,
  "customer": {
    "id": 5532,
    "name": "Sam Lee"
  },
  "sent_at": null,
  "delivered_at": null,
  "clicked_at": null,
  "created_at": "2026-10-12T15:05:00.000000Z",
  "not_sent_reason": {
    "code": "OPTED_OUT",
    "message": "The client opted out of messages."
  }
}
Error answers

401 The key is missing, wrong or revoked, or the signature is wrong.

{
  "error": {
    "code": "INVALID_API_KEY",
    "message": "The API key is missing, wrong or revoked."
  }
}

403 The plan doesn't include the API (Pro), or the account is suspended.

{
  "error": {
    "code": "PLAN_REQUIRED",
    "message": "The API is part of Pro. Upgrade to use it."
  }
}

404 Not found, or not this business's.

{
  "error": {
    "code": "NOT_FOUND",
    "message": "Resource not found."
  }
}

429 More than 120 calls this minute. Wait Retry-After seconds.

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many calls. Wait 42 seconds and try again."
  }
}

Account

GET/hooks/me

Check the key

The business and key name. Zapier uses it to test the connection.

Any key (read-only or full)

Example call

curl "https://api.onetouchreview.com/api/v1/hooks/me" \
  -H "Authorization: Bearer rev_YOUR_API_KEY" \
  -H "Accept: application/json"

Answer (200)

{
  "business_name": "Patel Law",
  "key_name": "Zapier"
}
Error answers

401 The key is missing, wrong or revoked, or the signature is wrong.

{
  "error": {
    "code": "INVALID_API_KEY",
    "message": "The API key is missing, wrong or revoked."
  }
}

403 The plan doesn't include the API (Pro), or the account is suspended.

{
  "error": {
    "code": "PLAN_REQUIRED",
    "message": "The API is part of Pro. Upgrade to use it."
  }
}

429 More than 120 calls this minute. Wait Retry-After seconds.

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many calls. Wait 42 seconds and try again."
  }
}

GET/hooks/locations

List locations

The business's locations, for location_id.

Any key (read-only or full)

Example call

curl "https://api.onetouchreview.com/api/v1/hooks/locations" \
  -H "Authorization: Bearer rev_YOUR_API_KEY" \
  -H "Accept: application/json"

Answer (200)

{
  "locations": [
    {
      "id": 12,
      "name": "Downtown"
    },
    {
      "id": 14,
      "name": "Northside"
    }
  ]
}
Error answers

401 The key is missing, wrong or revoked, or the signature is wrong.

{
  "error": {
    "code": "INVALID_API_KEY",
    "message": "The API key is missing, wrong or revoked."
  }
}

403 The plan doesn't include the API (Pro), or the account is suspended.

{
  "error": {
    "code": "PLAN_REQUIRED",
    "message": "The API is part of Pro. Upgrade to use it."
  }
}

429 More than 120 calls this minute. Wait Retry-After seconds.

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many calls. Wait 42 seconds and try again."
  }
}

GET/hooks/staff

List staff

Active staff members, for staff_member_id on a review request.

Any key (read-only or full)

Example call

curl "https://api.onetouchreview.com/api/v1/hooks/staff" \
  -H "Authorization: Bearer rev_YOUR_API_KEY" \
  -H "Accept: application/json"

Answer (200)

{
  "staff": [
    {
      "id": 77,
      "name": "Maria Gomez",
      "location_id": 12,
      "location_name": "Downtown"
    }
  ]
}
Error answers

401 The key is missing, wrong or revoked, or the signature is wrong.

{
  "error": {
    "code": "INVALID_API_KEY",
    "message": "The API key is missing, wrong or revoked."
  }
}

403 The plan doesn't include the API (Pro), or the account is suspended.

{
  "error": {
    "code": "PLAN_REQUIRED",
    "message": "The API is part of Pro. Upgrade to use it."
  }
}

429 More than 120 calls this minute. Wait Retry-After seconds.

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many calls. Wait 42 seconds and try again."
  }
}

GET/hooks/stats

Ratings and request counts

For each location: Google's rating and review count, each other review site's, and the review requests sent in the last 30 days and how many of those were clicked.

Any key (read-only or full)

location_id(query)

Only this location (from GET /hooks/locations). Not one of yours → 404 LOCATION_NOT_FOUND.

Example call

curl "https://api.onetouchreview.com/api/v1/hooks/stats" \
  -H "Authorization: Bearer rev_YOUR_API_KEY" \
  -H "Accept: application/json"

Answer (200)

{
  "locations": [
    {
      "id": 12,
      "name": "Downtown",
      "google": {
        "rating": 4.8,
        "count": 212
      },
      "sites": [
        {
          "platform": "avvo",
          "rating": 4.9,
          "count": 37
        },
        {
          "platform": "yelp",
          "rating": 4.5,
          "count": 18
        }
      ],
      "requests_last_30_days": {
        "sent": 64,
        "clicked": 29
      }
    }
  ]
}
Error answers

401 The key is missing, wrong or revoked, or the signature is wrong.

{
  "error": {
    "code": "INVALID_API_KEY",
    "message": "The API key is missing, wrong or revoked."
  }
}

403 The plan doesn't include the API (Pro), or the account is suspended.

{
  "error": {
    "code": "PLAN_REQUIRED",
    "message": "The API is part of Pro. Upgrade to use it."
  }
}

404 location_id is not one of your locations.

{
  "error": {
    "code": "LOCATION_NOT_FOUND",
    "message": "Location not found."
  }
}

429 More than 120 calls this minute. Wait Retry-After seconds.

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many calls. Wait 42 seconds and try again."
  }
}

Reviews

GET/hooks/google-reviews

List Google reviews

The newest 50 Google reviews. Reviews no longer on Google are left out unless include_removed=1; each review then has removed_at.

Any key (read-only or full)

include_removed(query)

1 to include reviews no longer on Google (each then has removed_at).

Example call

curl "https://api.onetouchreview.com/api/v1/hooks/google-reviews" \
  -H "Authorization: Bearer rev_YOUR_API_KEY" \
  -H "Accept: application/json"

Answer (200)

{
  "items": [
    {
      "id": 4410,
      "rating": 5,
      "comment": "Quick, kind and clear. Thank you!",
      "reviewer_name": "Nina P.",
      "location_id": 12,
      "location_name": "Downtown",
      "reply": "Thank you, Nina — we're glad we could help.",
      "created_at": "2026-10-11T18:20:00.000000Z"
    }
  ]
}
Error answers

401 The key is missing, wrong or revoked, or the signature is wrong.

{
  "error": {
    "code": "INVALID_API_KEY",
    "message": "The API key is missing, wrong or revoked."
  }
}

403 The plan doesn't include the API (Pro), or the account is suspended.

{
  "error": {
    "code": "PLAN_REQUIRED",
    "message": "The API is part of Pro. Upgrade to use it."
  }
}

429 More than 120 calls this minute. Wait Retry-After seconds.

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many calls. Wait 42 seconds and try again."
  }
}

GET/hooks/site-reviews

List reviews from other sites

Reviews from the other sites you connected (Avvo, Yelp, Facebook, BBB and more), newest posted first, 50 a page. Reviewers are shown by first name, as on the site.

Any key (read-only or full)

platform(query)

Only this site, for example avvo, yelp, facebook, bbb, findlaw, justia.

location_id(query)

Only this location (from GET /hooks/locations). Not one of yours → 404 LOCATION_NOT_FOUND.

since(query)

Only reviews posted on or after this day (YYYY-MM-DD).

cursor(query)

The next_cursor of the previous page.

Example call

curl "https://api.onetouchreview.com/api/v1/hooks/site-reviews" \
  -H "Authorization: Bearer rev_YOUR_API_KEY" \
  -H "Accept: application/json"

Answer (200)

{
  "reviews": [
    {
      "id": 801,
      "platform": "avvo",
      "location_id": 12,
      "rating": 5,
      "title": "Excellent lawyer",
      "body": "She explained every step and got a great result.",
      "reviewer_name": "James",
      "posted_on": "2026-10-09",
      "owner_response": null,
      "review_url": "https://www.avvo.com/attorneys/…/reviews.html"
    }
  ],
  "next_cursor": "MjAyNi0xMC0wOXw4MDE"
}
Error answers

401 The key is missing, wrong or revoked, or the signature is wrong.

{
  "error": {
    "code": "INVALID_API_KEY",
    "message": "The API key is missing, wrong or revoked."
  }
}

403 The plan doesn't include the API (Pro), or the account is suspended.

{
  "error": {
    "code": "PLAN_REQUIRED",
    "message": "The API is part of Pro. Upgrade to use it."
  }
}

404 location_id is not one of your locations.

{
  "error": {
    "code": "LOCATION_NOT_FOUND",
    "message": "Location not found."
  }
}

422 A parameter is not valid.

{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "The selected status is invalid.",
    "details": {
      "status": [
        "The selected status is invalid."
      ]
    }
  }
}

429 More than 120 calls this minute. Wait Retry-After seconds.

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many calls. Wait 42 seconds and try again."
  }
}

GET/hooks/private-feedback

List private feedback

The newest 50 written answers clients left on your review page (the "New private feedback" Zapier trigger).

Any key (read-only or full)

Example call

curl "https://api.onetouchreview.com/api/v1/hooks/private-feedback" \
  -H "Authorization: Bearer rev_YOUR_API_KEY" \
  -H "Accept: application/json"

Answer (200)

{
  "items": [
    {
      "id": 3301,
      "rating": 3,
      "private_feedback": "The wait was long, but the staff were kind.",
      "customer_name": "Sam Lee",
      "customer_phone": "+15125550188",
      "location_id": 12,
      "location_name": "Downtown",
      "review_request_id": 9120,
      "external_id": "case-0998",
      "responded_at": "2026-10-12T19:44:00.000000Z"
    }
  ]
}
Error answers

401 The key is missing, wrong or revoked, or the signature is wrong.

{
  "error": {
    "code": "INVALID_API_KEY",
    "message": "The API key is missing, wrong or revoked."
  }
}

403 The plan doesn't include the API (Pro), or the account is suspended.

{
  "error": {
    "code": "PLAN_REQUIRED",
    "message": "The API is part of Pro. Upgrade to use it."
  }
}

429 More than 120 calls this minute. Wait Retry-After seconds.

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many calls. Wait 42 seconds and try again."
  }
}

GET/hooks/assistant-leads

List leads from the card assistant

The newest 50 details forms and booking requests from the card assistant.

Any key (read-only or full)

Example call

curl "https://api.onetouchreview.com/api/v1/hooks/assistant-leads" \
  -H "Authorization: Bearer rev_YOUR_API_KEY" \
  -H "Accept: application/json"

Answer (200)

{
  "items": [
    {
      "id": "b118",
      "name": "Alex Moore",
      "phone": "+15125550142",
      "email": "alex@example.com",
      "card": {
        "id": 9,
        "kind": "business",
        "name": "Downtown"
      },
      "location": {
        "id": 12,
        "name": "Downtown"
      },
      "topic": "Consultation",
      "question": "Do you handle car accidents?",
      "booking": {
        "service": "Free consultation",
        "requested_at": "2026-10-15T15:00:00+00:00",
        "note": "Afternoons are best"
      },
      "conversation_url": "https://app.example.com/assistant/conversations/5521",
      "channel": "card",
      "page_url": null,
      "created_at": "2026-10-13T09:12:00.000000Z"
    }
  ]
}
Error answers

401 The key is missing, wrong or revoked, or the signature is wrong.

{
  "error": {
    "code": "INVALID_API_KEY",
    "message": "The API key is missing, wrong or revoked."
  }
}

403 The plan doesn't include the API (Pro), or the account is suspended.

{
  "error": {
    "code": "PLAN_REQUIRED",
    "message": "The API is part of Pro. Upgrade to use it."
  }
}

429 More than 120 calls this minute. Wait Retry-After seconds.

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many calls. Wait 42 seconds and try again."
  }
}

Zapier

GET/hooks/subscriptions

List webhook subscriptions

This key's subscriptions, newest first.

Any key (read-only or full)

Example call

curl "https://api.onetouchreview.com/api/v1/hooks/subscriptions" \
  -H "Authorization: Bearer rev_YOUR_API_KEY" \
  -H "Accept: application/json"

Answer (200)

{
  "subscriptions": [
    {
      "id": 31,
      "event": "google_review.created",
      "target_url": "https://hooks.example.com/rev",
      "created_at": "2026-10-01T09:00:00.000000Z",
      "last_delivered_at": "2026-10-11T18:21:02.000000Z",
      "last_status": 200
    }
  ]
}
Error answers

401 The key is missing, wrong or revoked, or the signature is wrong.

{
  "error": {
    "code": "INVALID_API_KEY",
    "message": "The API key is missing, wrong or revoked."
  }
}

403 The plan doesn't include the API (Pro), or the account is suspended.

{
  "error": {
    "code": "PLAN_REQUIRED",
    "message": "The API is part of Pro. Upgrade to use it."
  }
}

429 More than 120 calls this minute. Wait Retry-After seconds.

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many calls. Wait 42 seconds and try again."
  }
}

POST/hooks/subscriptions

Subscribe to an event

We POST each new event to target_url (a public https address); see Webhooks. Up to 25 subscriptions a key. Works with either kind of key.

Any key (read-only or full)

Example call

curl -X POST "https://api.onetouchreview.com/api/v1/hooks/subscriptions" \
  -H "Authorization: Bearer rev_YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"event":"google_review.created","target_url":"https://hooks.example.com/rev"}'

Answer (201)

{
  "id": 32,
  "event": "google_review.created",
  "target_url": "https://hooks.example.com/rev",
  "created_at": "2026-10-13T10:00:00.000000Z"
}
Error answers

401 The key is missing, wrong or revoked, or the signature is wrong.

{
  "error": {
    "code": "INVALID_API_KEY",
    "message": "The API key is missing, wrong or revoked."
  }
}

403 The plan doesn't include the API (Pro), or the account is suspended.

{
  "error": {
    "code": "PLAN_REQUIRED",
    "message": "The API is part of Pro. Upgrade to use it."
  }
}

422 Not valid, or TOO_MANY_SUBSCRIPTIONS.

{
  "error": {
    "code": "TOO_MANY_SUBSCRIPTIONS",
    "message": "This API key already has 25 subscriptions. Turn off a Zap or use another key."
  }
}

429 More than 120 calls this minute. Wait Retry-After seconds.

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many calls. Wait 42 seconds and try again."
  }
}

DELETE/hooks/subscriptions/{id}

Unsubscribe

Stops the deliveries at once.

Any key (read-only or full)

id(path, required)

The subscription id.

Example call

curl -X DELETE "https://api.onetouchreview.com/api/v1/hooks/subscriptions/12" \
  -H "Authorization: Bearer rev_YOUR_API_KEY" \
  -H "Accept: application/json"

Answer (204)

Unsubscribed. (no body)
Error answers

401 The key is missing, wrong or revoked, or the signature is wrong.

{
  "error": {
    "code": "INVALID_API_KEY",
    "message": "The API key is missing, wrong or revoked."
  }
}

403 The plan doesn't include the API (Pro), or the account is suspended.

{
  "error": {
    "code": "PLAN_REQUIRED",
    "message": "The API is part of Pro. Upgrade to use it."
  }
}

404 Not found, or not this business's.

{
  "error": {
    "code": "NOT_FOUND",
    "message": "Resource not found."
  }
}

429 More than 120 calls this minute. Wait Retry-After seconds.

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many calls. Wait 42 seconds and try again."
  }
}

Webhooks

Subscribe a URL to an event with POST /hooks/subscriptions. We send a POST with the JSON below and the headers X-Rev-Event, X-Rev-Delivery and, when the key has a signing secret, X-Rev-Signature. Skip repeats by the item's id. Answer with any 2xx. We try again after 1, 5 and 15 minutes; answer 410 to unsubscribe.

private_feedback.created

New private feedback

A client left written feedback on your review page. Delivered to each subscription for this event. See Delivery under google_review.created.

Body

{
  "id": 3301,
  "rating": 3,
  "private_feedback": "The wait was long, but the staff were kind.",
  "customer_name": "Sam Lee",
  "customer_phone": "+15125550188",
  "location_id": 12,
  "location_name": "Downtown",
  "review_request_id": 9120,
  "external_id": "case-0998",
  "responded_at": "2026-10-12T19:44:00.000000Z"
}

google_review.created

New Google review

A new Google review (left in the last 7 days) was saved.

Delivery. We POST the item as JSON with X-Rev-Event (the event), X-Rev-Delivery (a unique id per delivery; the same on retries is not guaranteed, dedupe by the item's id) and, when the key has a signing secret, X-Rev-Signature: t={unix seconds},v1={hex HMAC-SHA256(signing_secret, "{t}.{raw body}")}. Check it by computing the HMAC over "{t}.{raw body}" with your signing secret, comparing in constant time, and refusing a t more than 300 seconds old. Any 2xx is delivered; 410 deletes the subscription; anything else (or no answer in 10 s) is tried again after 60, 300 and 900 seconds.

Body

{
  "id": 4410,
  "rating": 5,
  "comment": "Quick, kind and clear. Thank you!",
  "reviewer_name": "Nina P.",
  "location_id": 12,
  "location_name": "Downtown",
  "reply": null,
  "created_at": "2026-10-11T18:20:00.000000Z"
}

assistant_lead

New lead from the card assistant

A visitor filled in the details form or asked for a booking.

Body

{
  "id": "b118",
  "name": "Alex Moore",
  "phone": "+15125550142",
  "email": "alex@example.com",
  "card": {
    "id": 9,
    "kind": "business",
    "name": "Downtown"
  },
  "location": {
    "id": 12,
    "name": "Downtown"
  },
  "topic": "Consultation",
  "question": "Do you handle car accidents?",
  "booking": {
    "service": "Free consultation",
    "requested_at": "2026-10-15T15:00:00+00:00",
    "note": "Afternoons are best"
  },
  "conversation_url": "https://app.example.com/assistant/conversations/5521",
  "channel": "card",
  "page_url": null,
  "created_at": "2026-10-13T09:12:00.000000Z"
}

Check the signature

Same format as signed requests: t=…,v1=…, an HMAC-SHA256 of "{t}.{raw body}" with the key's signing secret.

import crypto from 'node:crypto'

// header = req.headers['x-rev-signature'], rawBody = the request body exactly as received
function isFromOneTouchReview(header, rawBody, signingSecret) {
  const parts = Object.fromEntries(header.split(',').map((p) => p.trim().split('=')))
  const t = Number(parts.t)
  if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false
  const expected = crypto.createHmac('sha256', signingSecret).update(`${t}.${rawBody}`).digest('hex')
  const given = Buffer.from(parts.v1 ?? '', 'hex')
  return given.length === 32 && crypto.timingSafeEqual(given, Buffer.from(expected, 'hex'))
}

Rate limits and errors

120 calls a minute per key. Every answer has X-RateLimit-Limit and X-RateLimit-Remaining. Over the limit you get a 429 with Retry-After (seconds to wait). Errors always look like this:

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many calls. Wait 42 seconds and try again."
  }
}
  • 401 INVALID_API_KEY: the key is missing, wrong or revoked.
  • 402 SUBSCRIPTION_REQUIRED: the account has no active plan.
  • 403 PLAN_REQUIRED: the account isn't on Pro.
  • 403 API_KEY_READ_ONLY: a read-only key tried to send a review request.
  • 422 VALIDATION_FAILED: a field is missing or wrong; the message says which.

Zapier

No code needed: connect OneTouchReview to thousands of apps with Zapier, using an API key. Open OneTouchReview on Zapier

Try the API on the Pro trial

API access is part of Pro.

Coming soon