Replik OpenAPI 3.1 (JSON) · Français

Replik API v1

All of Replik in your information system: businesses and Google profile, reviews, AI reply suggestions and publishing. API access is free with every offer; each action is billed as in the app (Suns or your plan quotas).

1. Create an API key

In your Replik account, Tools → API menu: name the key, choose its scopes and copy the secret (shown only once). You must have accepted the terms and conditions in force.

2. Get a token (OAuth2 client credentials)

curl -X POST https://app.replik.app/api/v1/oauth/token \
  -u "rpk_votre_client_id:rps_votre_secret" \
  -d grant_type=client_credentials

Response: access_token (Bearer), valid for 1 hour.

3. Call the API

curl https://app.replik.app/api/v1/reviews?unanswered=true \
  -H "Authorization: Bearer rpt_..." -H "Accept-Language: fr"

curl -X POST https://app.replik.app/api/v1/reviews/123/suggestions \
  -H "Authorization: Bearer rpt_..." -H "Idempotency-Key: 6f1c2b7e" \
  -H "Content-Type: application/json" -d '{"tone": 6}'

curl -X POST https://app.replik.app/api/v1/reviews/123/replies \
  -H "Authorization: Bearer rpt_..." -H "Idempotency-Key: 9d4e0a11" \
  -H "Content-Type: application/json" -d '{"suggestion_id": 456}'

Errors: JSON error object with code, message and details. Limits per key: 120 reads, 30 writes and 20 generations per minute (RateLimit-* headers, 429 code). POST requests require the Idempotency-Key header: replaying the same request charges and publishes only once.

Webhooks

Declare an HTTPS URL (API page of your account, or POST /webhooks): Replik calls it for each chosen event. Check the signature before handling the call, and answer 2xx within 10 seconds; on failure, Replik retries for 24 hours.

Events: review.created · review.suggestion_ready · reply.published · reply.failed · review.removed · listing.alert · account.access_revoked · enrollment.completed · enrollment.failed · billing.limit_reached · billing.invoice_created

// PHP : vérifier l'en-tête Replik-Signature (t=…,v1=…)
$raw = file_get_contents('php://input');
parse_str(str_replace(',', '&', $_SERVER['HTTP_REPLIK_SIGNATURE']), $sig);
$expected = hash_hmac('sha256', $sig['t'] . '.' . $raw, getenv('REPLIK_WEBHOOK_SECRET'));
if (! hash_equals($expected, $sig['v1']) || abs(time() - (int) $sig['t']) > 300) {
    http_response_code(400); exit;
}
$event = json_decode($raw, true);   // id, type, created_at, account_id, data
// Ignorer un id déjà traité : un même événement peut être livré deux fois.
POST/api/v1/oauth/tokenGet an access token (OAuth2 client credentials)
ParameterInType
grant_typebodystring : client_credentials
client_idbodystring
client_secretbodystring
scopebodystring
GET/api/v1/accountAccount, Sun balance and terms
GET/api/v1/placesList businesses

Scope places:read.

GET/api/v1/places/{place_id}Get a business
ParameterInType
place_id *pathstring
PATCH/api/v1/places/{place_id}Update Replik settings of a business

Scope places:write. Only the fields sent are changed. Autopilot requires a plan.

ParameterInType
place_id *pathstring
GET/api/v1/places/{place_id}/listingGet the Google Business Profile (live)
ParameterInType
place_id *pathstring
PATCH/api/v1/places/{place_id}/listing/{section}Update a section of the Google Business Profile

Scope places:write. Sections: identity (title, primary_category, additional_categories), description, contact (primary_phone, additional_phones, website), hours (days.{DAY}.mode closed|open24|slots, days.{DAY}.slots[].open/close HH:MM), special_hours (special[].date, closed, open, close), status (OPEN|CLOSED_TEMPORARILY), attributes, lodging, services, menu. Only changed fields are sent to Google.

ParameterInType
place_id *pathstring
section *pathstring : identity | description | contact | hours | special_hours | status | attributes | lodging | services | menu
GET/api/v1/reviewsList reviews with their replies

Scope reviews:read. Newest first, cursor pagination.

ParameterInType
place_idquerystring
sincequerystring
untilquerystring
ratingqueryinteger
unansweredqueryboolean
sourcequerystring : google | tripadvisor | trustpilot | appstore | googleplay
limitqueryinteger
cursorquerystring
GET/api/v1/reviews/{review_id}Get a review with its replies
ParameterInType
review_id *pathinteger
POST/api/v1/reviews/{review_id}/suggestionsGenerate an AI reply suggestion

Scope reviews:write. Billed as in the app (Sun price or plan quota, free variants included). 402 insufficient_suns if needed.

ParameterInType
review_id *pathinteger
Idempotency-Key *headerstring
tonebodyinteger
instructionsbodystring
POST/api/v1/reviews/{review_id}/repliesPublish a reply

Scope reviews:write. Send suggestion_id (optionally with an edited text) or your own text. Google: queued (202), follow /publications/{id}. Connected App Store / Google Play apps: published directly (201). Other platforms: 422 platform_not_publishable.

ParameterInType
review_id *pathinteger
Idempotency-Key *headerstring
suggestion_idbodyinteger
textbodystring
GET/api/v1/publications/{publication_id}Follow a publication
ParameterInType
publication_id *pathinteger
GET/api/v1/accountsList attached client accounts (partners)

Scope accounts:manage, without Replik-Account header.

DELETE/api/v1/accounts/{account_id}Detach a client account (partners)

Scope accounts:manage. Businesses are suspended and data is deleted after 30 days.

ParameterInType
account_id *pathinteger
POST/api/v1/enrollmentsEnrol a client (partners)

Scope accounts:manage. Returns a one-time connect_url (valid 7 days) for the client: a Replik page with your name and logo, consent, then Google sign-in. The client is sent back to return_url?enrollment_id=…&status=completed|no_place|not_allowed&external_ref=…, and never gets access to the Replik interface. Webhooks: enrollment.completed, enrollment.failed. return_url must be https on a domain declared in your contract.

ParameterInType
Idempotency-Key *headerstring
emailbodystring
namebodystring
localebodystring : fr | en
return_urlbodystring
servicebodystring : essential | pro
placesbodystring : all | choose
external_refbodystring
GET/api/v1/enrollments/{enrollment_id}Follow an enrollment (partners)
ParameterInType
enrollment_id *pathinteger
DELETE/api/v1/enrollments/{enrollment_id}Cancel an unused enrollment link (partners)
ParameterInType
enrollment_id *pathinteger
GET/api/v1/billingCurrent month usage and invoices (partners)

Active places per plan, overage this month (Suns and € excl. VAT), spending cap, last 24 monthly invoices. Overage actions are refused with 402 once the monthly cap is reached (webhook billing.limit_reached).

GET/api/v1/webhooksList webhook endpoints

Scope webhooks:manage.

POST/api/v1/webhooksCreate a webhook endpoint

Scope webhooks:manage. Public HTTPS URL only. The signing secret is returned once. Events: review.created, review.suggestion_ready, reply.published, reply.failed, review.removed, listing.alert, account.access_revoked, enrollment.completed, enrollment.failed, billing.limit_reached, billing.invoice_created. Each call is a POST with a JSON body {id, type, created_at, account_id, data} (data.review uses the Review schema) and headers Replik-Event, Replik-Delivery (event id, stable across retries) and Replik-Signature: t=<unix time>,v1=<hex HMAC-SHA256 of "<t>.<raw body>" with your secret>. Answer 2xx within 10 seconds. Retries after 1 min, 5 min, 15 min, 1 h, 3 h, 6 h and 12 h; the endpoint is disabled after 50 consecutive failures.

ParameterInType
urlbodystring
eventsbodyarray
DELETE/api/v1/webhooks/{webhook_id}Delete a webhook endpoint
ParameterInType
webhook_id *pathinteger
POST/api/v1/webhooks/{webhook_id}/testSend a ping event
ParameterInType
webhook_id *pathinteger
GET/api/v1/webhooks/{webhook_id}/deliveriesLast 100 deliveries
ParameterInType
webhook_id *pathinteger