Send matter updates to Portico
Any system that can send a web request can keep Portico current: Zapier, Make, a scheduled script, or a hook in an on-premise case system. A firm admin issues the endpoint address and shared secret under Settings, Integrations.
1. Get the address and secret
In Portico, open Settings, then Integrations, then Inbound endpoint, and select Create endpoint. Portico shows the address once and the secret once. Copy both into your automation tool. The secret is stored encrypted and cannot be shown again; a new one can be issued at any time, which stops the old one working.
2. Send the request
Send an HTTP POST with a JSON body. In Zapier this is the Webhooks by Zapier action, set to POST, with Payload Type set to JSON.
POST https://<your Portico address>/api/public/inbound/<endpoint key>
Content-Type: application/json
x-portico-signature: sha256=<signature>
{
"event_id": "crm-4821",
"external_matter_id": "2024-0417",
"status": "Discovery",
"milestone_label": "Deposition",
"milestone_date": "2026-03-04",
"waiting_on": "Signed medical release from the client"
}3. The fields
- external_matter_id
- Required. Your system’s identifier for the matter. If it is not yet linked in Portico, Portico matches it to a matter with exactly that matter number and links it. Portico never creates a matter from an inbound event, and never matches on a client name.
- event_id
- Optional but recommended. Send the same id twice and the second is reported as a duplicate and ignored. Without it, Portico uses a fingerprint of the body.
- status
- Optional. Your own status wording. It moves the Portico stage only through a mapping a person has confirmed, with a plain-language client description. An unmapped status is listed for the firm to map and never moves a stage. A stage move never reaches the client on its own: it queues a draft update for a person to write and send.
- milestone_label
- Optional. The next thing expected on the matter, in plain words.
- milestone_date
- Optional. Format YYYY-MM-DD.
- waiting_on
- Optional. What the matter is waiting on. Keep it factual; the client can see it.
4. Sign the body
The signature is an HMAC-SHA256 of the exact request body, keyed with the shared secret, written as lower-case hex and prefixed with sha256=. Portico refuses any request whose signature does not match.
# Bash
BODY='{"event_id":"crm-4821","external_matter_id":"2024-0417","status":"Discovery"}'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$PORTICO_SECRET" -r | cut -d' ' -f1)
curl -X POST "$PORTICO_URL" \
-H "Content-Type: application/json" \
-H "x-portico-signature: sha256=$SIG" \
--data "$BODY"// Zapier Code by Zapier (JavaScript), then pass output.signature to the POST step
const crypto = require('crypto');
const body = JSON.stringify({
event_id: inputData.eventId,
external_matter_id: inputData.matterId,
status: inputData.status,
});
const signature = 'sha256=' + crypto
.createHmac('sha256', inputData.secret)
.update(body)
.digest('hex');
output = { body, signature };5. What comes back
Portico answers with JSON: applied with the list of fields that changed, duplicate when the event id has been seen, or ignored with a reason, most often that no Portico matter is linked to that external matter id. A wrong or missing signature returns 401. A malformed body returns 400.
{ "outcome": "applied", "changed": ["status", "waiting_on"], "stage_queued": true }Send only the fields listed here. Portico does not accept documents, messages, or client contact details on this endpoint.