API Documentation

API Documentation

Integrate review management into your workflow. Retrieve reviews, manage organizations, send review request invites, and receive real-time webhook notifications.

Base URL
https://gumado.com/api/v1
Auth
Bearer Token
Rate Limit
60 requests / minute
Format
application/json

Authentication

All API requests require a valid API token. Tokens are created from your account settings under API & Webhooks. Each token can be scoped to specific permissions.

How to authenticate

Include your API token in the Authorization header of every request:

Authorization Header
Authorization: Bearer your-api-token

Token Permissions

When creating a token, you can assign one or more permission groups. Endpoints will only be accessible if your token has the required permissions.

Permission Access
reviews:read View reviews
request:read View campaigns
request:create Send review invites
organizations:read View organizations
organizations:create Create organizations
organizations:update Update organizations
organizations:delete Delete organizations

Keep your tokens secure

Never share your API token in public repositories, client-side code, or URLs. Treat it like a password. If a token is compromised, revoke it immediately from your account settings.

Rate Limiting

The API enforces rate limits to ensure fair usage and platform stability. All authenticated requests share the same rate limit bucket.

60
Requests per minute
429
Status when exceeded
60s
Window resets every

Response Headers

Every response includes headers to help you track your rate limit usage:

Header Description
X-RateLimit-Limit Maximum requests per window (60)
X-RateLimit-Remaining Remaining requests in current window
Retry-After Seconds to wait before retrying (only on 429)

Best practice

Implement exponential backoff when you receive a 429 response. Check the Retry-After header for the exact wait time.

Errors

The API uses standard HTTP status codes to indicate the success or failure of a request. Errors return a JSON body with a message field describing the issue.

Code Status Description
200 OK Request succeeded
201 Created Resource successfully created
202 Accepted Request accepted and queued for processing
401 Unauthenticated Missing or invalid API token
403 Forbidden Token lacks required permissions for this action
404 Not Found The requested resource does not exist
422 Validation Error Request body failed validation rules
429 Too Many Requests Rate limit exceeded
500 Server Error Something went wrong on our end

Validation Error Response

422 Validation Error
{
    "message": "The email field is required when phone is not present.",
    "errors": {
        "email": [
            "The email field is required when phone is not present."
        ]
    }
}

Pagination

List endpoints return paginated results with 10 items per page. Use the page query parameter to navigate through results.

Paginated Response Structure
{
    "data": [...],
    "links": {
        "first": "https://gumado.com/api/v1/reviews?page=1",
        "last": "https://gumado.com/api/v1/reviews?page=5",
        "prev": null,
        "next": "https://gumado.com/api/v1/reviews?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 5,
        "per_page": 10,
        "to": 10,
        "total": 48
    }
}

List Reviews

GET /api/v1/reviews

Retrieve a paginated list of reviews across all connected sources. Filter by rating, organization, location, or review source.

Requires reviews:read

Query Parameters

Parameter Type Description
rating integer Filter by rating (1-5)
organization_id integer Filter by organization
location_id integer Filter by location
source_names[] array Filter by source names (e.g. Google, Facebook)
page integer Page number (default: 1)

Example Request

cURL
curl https://gumado.com/api/v1/reviews?rating=5&source_names[]=Google \
  -H "Authorization: Bearer your-api-token" \
  -H "Accept: application/json"

Example Response

200 OK
{
    "data": [
        {
            "id": 142,
            "organization_id": 1,
            "location_id": 3,
            "author": "Sarah Johnson",
            "date": "2025-12-15T10:30:00.000000Z",
            "rating": 5,
            "title": null,
            "message": "Outstanding service! The team went above and beyond.",
            "source": "Google",
            "source_logo": "https://example.com/logos/google.svg",
            "avatar": "https://lh3.googleusercontent.com/a/photo.jpg",
            "reply": "Thank you Sarah! We appreciate your kind words.",
            "reply_date": "2025-12-16T09:00:00.000000Z"
        }
    ],
    "links": { ... },
    "meta": { ... }
}

Organizations

Organizations represent your business locations or brands. Manage them via the API to programmatically create, update, and delete organizations.

List Organizations

GET /api/v1/organizations

Returns a paginated list of all organizations accessible to the authenticated user.

Requires organizations:read
cURL
curl https://gumado.com/api/v1/organizations \
  -H "Authorization: Bearer your-api-token" \
  -H "Accept: application/json"
200 OK
{
    "data": [
        {
            "id": 1,
            "name": "Acme Dental Clinic",
            "created_at": "2025-01-15T08:30:00.000000Z",
            "updated_at": "2025-06-20T14:22:00.000000Z"
        }
    ],
    "links": { ... },
    "meta": { ... }
}

Get Organization

GET /api/v1/organizations/{'{id}'}

Retrieve a single organization by its ID.

Requires organizations:read

Create Organization

POST /api/v1/organizations

Create a new organization. The name must be unique across your account.

Requires organizations:create

Request Body

Field Type Description
name required string Organization name (max 255 characters, must be unique)
logo file Logo image (png, jpg, jpeg, svg — max 250KB)
cURL
curl -X POST https://gumado.com/api/v1/organizations \
  -H "Authorization: Bearer your-api-token" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name": "Downtown Branch"}'

Update Organization

PUT /api/v1/organizations/{'{id}'}

Update an existing organization's name or logo.

Requires organizations:update

Delete Organization

DELETE /api/v1/organizations/{'{id}'}

Permanently delete an organization. This action cannot be undone. You must have at least one remaining organization.

Requires organizations:delete
cURL
curl -X DELETE https://gumado.com/api/v1/organizations/1 \
  -H "Authorization: Bearer your-api-token" \
  -H "Accept: application/json"
200 OK
{
    "message": "Organization deleted successfully."
}

List Campaigns

GET /api/v1/request-reviews/campaigns

Retrieve your review request campaigns. Use campaign UUIDs to send invites via the Send Invites endpoint.

Requires request:read

Query Parameters

ParameterTypeDescription
organization_idintegerFilter campaigns by organization
searchstringSearch campaigns by name
cURL
curl https://gumado.com/api/v1/request-reviews/campaigns \
  -H "Authorization: Bearer your-api-token" \
  -H "Accept: application/json"
200 OK
{
    "data": [
        {
            "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
            "name": "Post-Visit Follow Up"
        },
        {
            "id": "f9e8d7c6-b5a4-3210-fedc-ba0987654321",
            "name": "Monthly Customer Outreach"
        }
    ],
    "links": { ... },
    "meta": { ... }
}

Send Review Invite

POST /api/v1/request-reviews/campaigns/{'{campaign}'}/invite

Send a review request invite to a contact via email, SMS, or WhatsApp. This is the primary endpoint for automating review requests from your CRM, POS, or booking system.

Requires request:read + request:create

Path Parameters

ParameterTypeDescription
campaign requireduuidCampaign UUID (from List Campaigns or dashboard)

Request Body

FieldTypeDescription
email conditionalstringContact's email address. Required when phone is not provided.
phone conditionalstringPhone in E.164 format (e.g. +14275238194). Required when email is not provided.
first_namestringContact's first name (max 255 characters)
last_namestringContact's last name (max 255 characters)
send_after_hoursintegerHours to wait before sending. 0 = send as soon as possible (respects campaign send window). null = use campaign default.

Example: Send immediately via email

cURL
curl -X POST https://gumado.com/api/v1/request-reviews/campaigns/a1b2c3d4-e5f6-7890-abcd-ef1234567890/invite \
  -H "Authorization: Bearer your-api-token" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "sarah.johnson@example.com",
    "first_name": "Sarah",
    "last_name": "Johnson",
    "send_after_hours": 0
  }'
202 Accepted
{
    "id": "c7d8e9f0-1234-5678-abcd-ef9876543210",
    "message": "Invites sent successfully."
}

Example: Send via SMS with delay

cURL
curl -X POST https://gumado.com/api/v1/request-reviews/campaigns/a1b2c3d4-e5f6-7890-abcd-ef1234567890/invite \
  -H "Authorization: Bearer your-api-token" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+14275238194",
    "first_name": "James",
    "send_after_hours": 2
  }'

Important Behavior Notes

Duplicate contacts are handled gracefully

If the same contact (email or phone) is submitted again within the campaign's duplicate protection window (default: 14 days), the request is silently accepted and the contact is marked as ignored. No error is returned — you will still receive a 202 response. This means you can safely send invites from your system without worrying about duplicate checks on your end.

Returning customers outside the dedup window

If a contact was previously invited but the duplicate protection window has passed, they will be re-added to the campaign and receive a new invite. This is useful for repeat customers.

Unsubscribed contacts

Contacts who have previously unsubscribed will not be sent new invites, even if submitted via the API. The request will still return 202 without error. Their opt-out preference is always respected.

Invites respect the campaign send window

All invites are scheduled within your campaign's configured send window (UTC). If a request is submitted outside the window, the invite will be queued and sent at the start of the next available window. For example, if your campaign sends between 07:0016:00 UTC and you submit at 02:00 UTC with send_after_hours: 0, the invite will be sent at 07:00 UTC. Campaigns with no send window configured (all-day) are unaffected.

Delivery channels depend on campaign configuration

The invite will be sent via email, SMS, or WhatsApp depending on what channels are configured in your campaign steps. Providing both email and phone ensures maximum reach across all configured channels.

List Review Sources

GET /api/v1/sources

Retrieve all available review sources (Google, Facebook, Yelp, Trustpilot, etc.) with their capabilities and logos.

Any valid token
cURL
curl https://gumado.com/api/v1/sources \
  -H "Authorization: Bearer your-api-token" \
  -H "Accept: application/json"
200 OK
{
    "data": [
        {
            "id": 1,
            "name": "Google",
            "url": "https://google.com",
            "logo": "https://example.com/logos/google.svg",
            "available": true,
            "can_collect_reviews": true,
            "deep_linking_supported": true
        },
        {
            "id": 2,
            "name": "Facebook",
            "url": "https://facebook.com",
            "logo": "https://example.com/logos/facebook.svg",
            "available": true,
            "can_collect_reviews": true,
            "deep_linking_supported": true
        }
    ],
    "links": { ... },
    "meta": { ... }
}

List Countries

GET /api/v1/countries

Retrieve the full list of supported countries with their ISO 3166-1 alpha-2 codes. Useful for populating country selectors in your integration.

Any valid token
200 OK
[
    { "id": "US", "name": "United States" },
    { "id": "GB", "name": "United Kingdom" },
    { "id": "CA", "name": "Canada" },
    ...
]

Current User

GET /api/v1/me

Retrieve the authenticated user's basic information. Useful for verifying your API token and confirming which account it belongs to.

Any valid token
200 OK
{
    "id": 1,
    "name": "John Smith",
    "email": "john@example.com"
}
Webhooks

Webhooks

Webhooks allow you to receive real-time HTTP notifications when events occur in your account. Instead of polling the API, configure a webhook URL and we will send a POST request to your endpoint whenever something happens.

How It Works

  1. 1
    Configure your webhook
    Go to Settings → API & Webhooks in your dashboard and add your endpoint URL with the events you want to subscribe to.
  2. 2
    An event occurs
    For example, a new Google review comes in for one of your locations.
  3. 3
    We send a POST request
    Your endpoint receives a JSON payload with the event data. Respond with a 2xx status to acknowledge receipt.

Delivery Details

PropertyValue
HTTP MethodPOST
Content-Typeapplication/json
User-AgentReviewManagement/V1
Retry PolicyUp to 10 retries over 5 minutes with exponential backoff
Timeout30 seconds per attempt

Best practice

Respond quickly (within 5 seconds) and process webhook data asynchronously. If your endpoint takes too long, the request may time out and trigger a retry.

Webhook Events

Subscribe to the events relevant to your integration. Each webhook payload includes a webhook_event field identifying the event type.

Event Triggered When
review-created A new review is received from any connected source
review-updated An existing review is modified (e.g. reply added, rating changed)
Organizations
organization-created A new organization is created
organization-updated An organization's details are modified
organization-deleted An organization is deleted
Locations
location-created A new location is added to an organization
location-updated A location's details are modified
location-deleted A location is removed

Webhook Payloads

Below are example payloads for each webhook event type. All payloads include the webhook_event field.

review-created / review-updated

Sent when a review is received or modified.

Payload
{
    "webhook_event": "review-created",
    "id": 142,
    "organization_id": 1,
    "location_id": 3,
    "source_name": "google",
    "identifier": "AbcXyz123",
    "avatar": "https://lh3.googleusercontent.com/a/photo.jpg",
    "author": "Sarah Johnson",
    "rating": 5,
    "original_rating": 5,
    "title": null,
    "message": "Outstanding service! The team went above and beyond.",
    "url": "https://maps.google.com/review/...",
    "verified": true,
    "replied": false,
    "reply_message": null,
    "reply_url": null,
    "hidden": false,
    "reply_published_on": null,
    "published_on": "2025-12-15T10:30:00+00:00",
    "review_updated_on": null,
    "updated_at": "2025-12-15T10:35:00+00:00",
    "created_at": "2025-12-15T10:35:00+00:00",
    "meta": {}
}

organization-created / organization-updated

Sent when an organization is created or modified.

Payload
{
    "webhook_event": "organization-created",
    "id": 1,
    "user_id": 1,
    "name": "Acme Dental Clinic",
    "updated_at": "2025-12-15T10:30:00+00:00",
    "created_at": "2025-12-15T10:30:00+00:00"
}

organization-deleted

Sent when an organization is deleted. Contains minimal data.

Payload
{
    "webhook_event": "organization-deleted",
    "id": 1
}

location-created / location-updated

Sent when a location is added or modified.

Payload
{
    "webhook_event": "location-created",
    "id": 3,
    "organization_id": 1,
    "name": "Downtown Branch",
    "updated_at": "2025-12-15T10:30:00+00:00",
    "created_at": "2025-12-15T10:30:00+00:00"
}

location-deleted

Sent when a location is removed. Contains minimal data.

Payload
{
    "webhook_event": "location-deleted",
    "id": 3
}

Need help? Contact us from your account dashboard.

© 2026 Gumado