Automation
Add the site when the client is new
I got tired of opening the dashboard for every new retainer. The API creates the site, turns the status page on, and adds a path. It uses the same checks as the forms. It does not start a check by itself.
The key
Brand settings, then API keys. The full key is shown once. I store only a hash. Send Authorization: Bearer rp_live_… on every call. The key can only touch that account, and the account needs an active subscription. The limit is 60 requests a minute per key.
Create the site
name is required, 80 characters at most. url is an http or https address. cadence is optional: daily, twice_daily, weekly, or monthly. If I leave cadence out, the account default is used. A new site does not run a check.
curl -sS -X POST https://retainerproof.com/api/v1/sites \
-H "Authorization: Bearer rp_live_…" \
-H "Content-Type: application/json" \
-d '{"name":"Harbor","url":"https://harbor.example","cadence":"weekly"}'
The response is 201 and a site object. Keep site.id and site.digestUrl. statusPageUrl is null until the status page is on. Starter allows 5 sites, Studio 25, Agency 100. At the limit the response is 409 with error set to site_limit. Existing sites stay. Apps and proof packs do not use a site slot.
Turn the status page on
statusEnabled: true publishes the page and creates a token the same way the dashboard does. Turning it off keeps the token and returns statusPageUrl: null. Turning it on again uses the same link.
curl -sS -X PATCH https://retainerproof.com/api/v1/sites/SITE_ID \
-H "Authorization: Bearer rp_live_…" \
-H "Content-Type: application/json" \
-d '{"statusEnabled":true}'
Read site.statusPageUrl from that response. That URL is public. The digest URL is still the secret client link. I do not put the digest URL in a sitemap.
Add a status path
This is an extra check, the same one as Extra checks on the site page. label is required, 60 characters at most. url can be a path such as /api/health or a full http or https URL. expected is 2xx, 3xx, any, or an HTTP status code. intervalMode is uptime or site. A site allows 12 extra checks. The 13th is 409 with error set to target_limit. A duplicate URL is 422.
curl -sS -X POST https://retainerproof.com/api/v1/sites/SITE_ID/targets \
-H "Authorization: Bearer rp_live_…" \
-H "Content-Type: application/json" \
-d '{"label":"Health","url":"/api/health","expected":"200"}'
Skip this call when the site has no extra URL. The homepage is still checked on its own. DELETE /api/v1/sites/SITE_ID removes that care site. I only send it when I mean to delete the site.
n8n when a CRM adds a client
I do not connect to a particular CRM. If n8n already receives a new client from yours, add HTTP Request nodes after that trigger.
- Trigger: the new-client event your CRM already sends into n8n. Map the client name and the public URL from that item. If either is missing, stop.
- HTTP Request. Method POST. URL
https://retainerproof.com/api/v1/sites. HeaderAuthorization: Bearer rp_live_…andContent-Type: application/json. Keep the key in a header credential. - JSON body. Use the CRM name and URL. Cadence is optional.
{"name":"Harbor","url":"https://harbor.example","cadence":"weekly"}
- Read
site.idfrom the response. - Second HTTP Request. Method PATCH. URL
https://retainerproof.com/api/v1/sites/plus that id. JSON body{"statusEnabled":true}. Storesite.statusPageUrlif you want to send it back to the CRM. - Third HTTP Request, only when you know a health path. Method POST. URL
https://retainerproof.com/api/v1/sites/plus that id plus/targets. JSON body{"label":"Health","url":"/api/health","expected":"200"}.
Stop the workflow on 409 (the plan is full, or the site already has 12 paths) and on 429 (wait for Retry-After). Do not retry 409 in a loop.
The same steps in Zapier
Zapier does not have a RetainerProof app in this setup. Use the CRM's new-client trigger, then an HTTP request for each call above: create, then PATCH statusEnabled, then the path if you have one. The headers and JSON are the same as the curl examples.
Release notes are a separate call. I wrote that up on release notes. Field-by-field reference: API.