{"openapi":"3.1.0","info":{"title":"Replik API","version":"1.0.0","description":"Programmatic access to Replik: businesses, Google profile, reviews, AI reply suggestions and publishing.\n\nAuthentication: OAuth2 client credentials. Create an API key in your Replik account (Account → API), exchange it for a 1-hour Bearer token on /oauth/token.\n\nBilling: API access is free on every plan; actions are billed exactly as in the app (Suns or plan quotas).\n\nErrors: {\"error\": {\"code\", \"message\", \"details\"}}. Set Accept-Language: fr or en for messages.\n\nPartners: with the accounts:manage scope, add the header Replik-Account: <account_id> to any endpoint to act for an attached client account (404 account_not_found otherwise). Client events are also delivered to the partner's webhooks, with external_ref.","contact":{"email":"hello@replik.app"}},"servers":[{"url":"https://app.replik.app/api/v1"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"},"oauth2":{"type":"oauth2","flows":{"clientCredentials":{"tokenUrl":"/api/v1/oauth/token","scopes":{"places:read":"Read businesses and Google profiles","places:write":"Change business settings and Google profiles","reviews:read":"Read reviews, replies and publications","reviews:write":"Generate reply suggestions and publish replies","webhooks:manage":"Manage webhook endpoints","accounts:manage":"Partners only: manage attached client accounts and act for them (Replik-Account header)"}}}}},"responses":{"Error":{"description":"Error (401 invalid_token, 402 insufficient_suns, 403 insufficient_scope, 404 not_found, 409 terms_not_accepted / already_published, 422 validation_failed, 429 rate_limited)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object"}}}}}}}}},"schemas":{"Place":{"type":"object","properties":{"place_id":{"type":"string"},"google_location":{"type":"string"},"name":{"type":"string"},"city":{"type":"string"},"category":{"type":"string"},"rating":{"type":"number"},"reviews_count":{"type":"integer"},"unanswered_count":{"type":"integer"},"active":{"type":"boolean"},"subscription":{"type":["object","null"]},"settings":{"$ref":"#/components/schemas/PlaceSettings"}}},"PlaceSettings":{"type":"object","properties":{"tone":{"type":"integer","minimum":0,"maximum":9,"description":"0 very formal … 9 warm"},"greeting":{"type":"string","enum":["first_name","title_last_name"]},"negative_review_contact":{"type":"boolean"},"support_phone":{"type":["string","null"]},"support_email":{"type":["string","null"]},"signature":{"type":["string","null"]},"report_frequency_days":{"type":"integer"},"autopilot":{"type":"object","properties":{"enabled":{"type":"boolean"},"delay_hours":{"type":"integer","enum":[1,2,3,6,12,24,48,72]},"min_rating":{"type":"integer","enum":[5,4,3,2,1]}}},"platforms":{"type":"object","properties":{"tripadvisor_url":{"type":["string","null"]},"trustpilot_url":{"type":["string","null"]},"googleplay_url":{"type":["string","null"]},"appstore_url":{"type":["string","null"]}}}}},"Review":{"type":"object","properties":{"review_id":{"type":"integer"},"place_id":{"type":"string"},"source":{"type":"string"},"rating":{"type":"integer"},"text":{"type":"string"},"author":{"type":"object"},"created_at":{"type":"string","format":"date-time"},"replies":{"type":"array","items":{"$ref":"#/components/schemas/Reply"}},"auto_publish_at":{"type":["string","null"],"format":"date-time"}}},"Reply":{"type":"object","properties":{"reply_id":{"type":"integer"},"text":{"type":"string"},"status":{"type":"string","enum":["online","draft","publishing","published","failed_retryable","failed","validated"]},"origin":{"type":"string","enum":["imported","replik"]}}}}},"paths":{"/oauth/token":{"post":{"summary":"Get an access token (OAuth2 client credentials)","tags":["Authentication"],"security":[],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["grant_type"],"properties":{"grant_type":{"type":"string","enum":["client_credentials"]},"client_id":{"type":"string"},"client_secret":{"type":"string"},"scope":{"type":"string","description":"Optional, space-separated subset of the key scopes"}}}}}},"responses":{"200":{"description":"Token","content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string"},"token_type":{"type":"string"},"expires_in":{"type":"integer"},"scope":{"type":"string"}}}}}},"400":{"description":"unsupported_grant_type / invalid_scope"},"401":{"description":"invalid_client"}}}},"/account":{"get":{"summary":"Account, Sun balance and terms","tags":["Account"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Account","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/places":{"get":{"summary":"List businesses","tags":["Places"],"security":[{"bearerAuth":[]}],"description":"Scope places:read.","responses":{"200":{"description":"Businesses","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Place"}}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/places/{place_id}":{"get":{"summary":"Get a business","tags":["Places"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"place_id","in":"path","required":true,"description":"Google place ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Business","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}},"patch":{"summary":"Update Replik settings of a business","tags":["Places"],"security":[{"bearerAuth":[]}],"description":"Scope places:write. Only the fields sent are changed. Autopilot requires a plan.","parameters":[{"name":"place_id","in":"path","required":true,"description":"Google place ID","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/PlaceSettings"},{"type":"object","properties":{"active":{"type":"boolean"}}}]}}}},"responses":{"200":{"description":"Updated business","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/places/{place_id}/listing":{"get":{"summary":"Get the Google Business Profile (live)","tags":["Google profile"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"place_id","in":"path","required":true,"description":"Google place ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Google profile, attributes, lodging, services, menus","content":{"application/json":{"schema":{"type":"object"}}}},"502":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/places/{place_id}/listing/{section}":{"patch":{"summary":"Update a section of the Google Business Profile","tags":["Google profile"],"security":[{"bearerAuth":[]}],"description":"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.","parameters":[{"name":"place_id","in":"path","required":true,"description":"Google place ID","schema":{"type":"string"}},{"name":"section","in":"path","required":true,"schema":{"type":"string","enum":["identity","description","contact","hours","special_hours","status","attributes","lodging","services","menu"]}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Updated Google profile","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/reviews":{"get":{"summary":"List reviews with their replies","tags":["Reviews"],"security":[{"bearerAuth":[]}],"description":"Scope reviews:read. Newest first, cursor pagination.","parameters":[{"name":"place_id","in":"query","schema":{"type":"string"}},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"until","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"rating","in":"query","schema":{"type":"integer","minimum":1,"maximum":5}},{"name":"unanswered","in":"query","schema":{"type":"boolean"}},{"name":"source","in":"query","schema":{"type":"string","enum":["google","tripadvisor","trustpilot","appstore","googleplay"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Reviews","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Review"}},"next_cursor":{"type":["string","null"]}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/reviews/{review_id}":{"get":{"summary":"Get a review with its replies","tags":["Reviews"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"review_id","in":"path","required":true,"description":"Review ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"Review","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/reviews/{review_id}/suggestions":{"post":{"summary":"Generate an AI reply suggestion","tags":["Replies"],"security":[{"bearerAuth":[]}],"description":"Scope reviews:write. Billed as in the app (Sun price or plan quota, free variants included). 402 insufficient_suns if needed.","parameters":[{"name":"review_id","in":"path","required":true,"description":"Review ID","schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique key per operation (max 100 chars). Retrying with the same key and body returns the stored response: no second charge or publication.","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"tone":{"type":"integer","minimum":0,"maximum":9},"instructions":{"type":"string","maxLength":2500}}}}}},"responses":{"201":{"description":"Suggestion","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"suggestion_id":{"type":"integer"},"text":{"type":"string"},"charged":{"type":"boolean"},"cost_suns":{"type":"number"},"free_variants_left":{"type":"integer"}}}}}}}},"402":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/reviews/{review_id}/replies":{"post":{"summary":"Publish a reply","tags":["Replies"],"security":[{"bearerAuth":[]}],"description":"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.","parameters":[{"name":"review_id","in":"path","required":true,"description":"Review ID","schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique key per operation (max 100 chars). Retrying with the same key and body returns the stored response: no second charge or publication.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"suggestion_id":{"type":"integer"},"text":{"type":"string","maxLength":4000}}}}}},"responses":{"202":{"description":"Queued for publication","content":{"application/json":{"schema":{"type":"object"}}}},"201":{"description":"Published","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/publications/{publication_id}":{"get":{"summary":"Follow a publication","tags":["Replies"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"publication_id","in":"path","required":true,"description":"Publication ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"Publication (queued, publishing, published, failed…)","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/accounts":{"get":{"summary":"List attached client accounts (partners)","tags":["Partners"],"security":[{"bearerAuth":[]}],"description":"Scope accounts:manage, without Replik-Account header.","responses":{"200":{"description":"Client accounts: account_id, external_ref, service, status, google_access, places","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/accounts/{account_id}":{"delete":{"summary":"Detach a client account (partners)","tags":["Partners"],"security":[{"bearerAuth":[]}],"description":"Scope accounts:manage. Businesses are suspended and data is deleted after 30 days.","parameters":[{"name":"account_id","in":"path","required":true,"description":"Client account ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"Detached","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/enrollments":{"post":{"summary":"Enrol a client (partners)","tags":["Partners"],"security":[{"bearerAuth":[]}],"description":"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.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique key per operation (max 100 chars). Retrying with the same key and body returns the stored response: no second charge or publication.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","return_url"],"properties":{"email":{"type":"string","format":"email"},"name":{"type":"string"},"locale":{"type":"string","enum":["fr","en"]},"return_url":{"type":"string","format":"uri"},"service":{"type":"string","enum":["essential","pro"]},"places":{"type":"string","enum":["all","choose"]},"external_ref":{"type":"string","description":"Your client ID, returned everywhere (accounts, webhooks, invoice annex)"}}}}}},"responses":{"201":{"description":"Enrollment with connect_url","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/enrollments/{enrollment_id}":{"get":{"summary":"Follow an enrollment (partners)","tags":["Partners"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"enrollment_id","in":"path","required":true,"description":"Enrollment ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"status: pending, completed, expired, canceled, no_place; account_id; places","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}},"delete":{"summary":"Cancel an unused enrollment link (partners)","tags":["Partners"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"enrollment_id","in":"path","required":true,"description":"Enrollment ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"Canceled","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/billing":{"get":{"summary":"Current month usage and invoices (partners)","tags":["Partners"],"security":[{"bearerAuth":[]}],"description":"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).","responses":{"200":{"description":"Usage and invoices","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/webhooks":{"get":{"summary":"List webhook endpoints","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"description":"Scope webhooks:manage.","responses":{"200":{"description":"Endpoints","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}},"post":{"summary":"Create a webhook endpoint","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"description":"Scope webhooks:manage. Public HTTPS URL only. The signing secret is returned once.\n\nEvents: 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.\n\nEach 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.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","events"],"properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["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"]}}}}}}},"responses":{"201":{"description":"Endpoint with its secret","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/webhooks/{webhook_id}":{"delete":{"summary":"Delete a webhook endpoint","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"webhook_id","in":"path","required":true,"description":"Webhook ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/webhooks/{webhook_id}/test":{"post":{"summary":"Send a ping event","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"webhook_id","in":"path","required":true,"description":"Webhook ID","schema":{"type":"integer"}}],"responses":{"202":{"description":"Ping queued","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/webhooks/{webhook_id}/deliveries":{"get":{"summary":"Last 100 deliveries","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"webhook_id","in":"path","required":true,"description":"Webhook ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"Deliveries","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}}}}