Sentra SchedulerField service
Setup & integrations › API & webhooks

Sentra Scheduler API & webhooks

A documented REST API, a public API for the request widget and signed webhooks, so Sentra Scheduler fits with the other systems your company runs.

Three ways to connect

REST API v1

Everything your office can do in the portal, at {company}.sentrascheduler.com/api/v1, with a signed-in staff session.

Public API

What the request widget uses, at api.sentrascheduler.com/public/v1 with your company’s public key.

Webhooks

Sentra Scheduler calls your system when a job is created, assigned, changes status, is closed or reopened.

How a webhook integration works

  1. Sentra Scheduler

    A job changes

    A customer requests it, the office assigns it, a technician closes it. Every change is on the job’s timeline.

  2. Sentra Scheduler

    Sentra Scheduler sends a webhook

    A JSON event goes to each endpoint subscribed to it, signed with HMAC SHA-256 and your endpoint’s secret.

  3. Side path:

    Failed deliveries are retried

    Up to six attempts with backoff: after 10 seconds, 1 minute, 5 minutes, 30 minutes and 2 hours.

    Every attempt in the delivery log

  4. Your system

    Your system acts on it

    Update your accounting or CRM, post to a chat channel or a data warehouse. Read more through the REST API.

Documented with OpenAPI 3

About 150 endpoints, described in one OpenAPI 3 file that’s updated with every endpoint, with interactive docs served by the API.

  • Docs at /api/docs; the spec at /api/openapi.yaml
  • JSON in and out, with one error shape: {"error": {"code", "message", "fields"}}
  • Cursor paging: ?limit=50&cursor=… returns data and next_cursor
  • Updates need If-Match with the record’s version: 428 without it, 409 when it’s stale
  • Creates take an Idempotency-Key, so a retried request doesn’t act twice
  • Rate limits per staff session, and per IP and company key on the public API

Webhooks

Admins add endpoints and pick events in the admin settings, where every delivery and its response code is logged. Jobs are called requests in the API.

  • Events:
    • request.created
    • request.assigned
    • request.status_changed
    • request.closed
    • request.reopened
  • Headers: X-Civic311-Event, X-Civic311-Delivery, X-Civic311-Timestamp and X-Civic311-Signature
  • Signature: sha256= plus an HMAC SHA-256 of {timestamp}.{body} with the endpoint’s secret
  • Up to six attempts with backoff when your endpoint doesn’t answer with success
  • HTTPS endpoints on public addresses only; payloads carry the job, not your customers’ contact details

Public API

The request widget uses the public API, chosen by your company’s public key in the X-City-Key header.

  • Job types and your request form settings
  • Request service, with photos
  • Track a job by number, follow it, leave feedback
  • AI chat
  • Knowledge base search and articles

Sign-in, exports and security

The staff API uses the same sign-in as the portal; data leaves the system only in ways your admins control.

  • Staff API calls use a signed-in staff session (Authorization: Bearer); permissions are enforced in the API by role and team
  • Exports: jobs as CSV, the audit log as CSV, and reports as CSV or PDF, also on a schedule by email
  • Moving in: the importer reads a CSV export from your old system, with undo
  • Every company’s data is separated, and changes are recorded in an audit log

Code samples

Request service through the public API

curl -X POST https://api.sentrascheduler.com/public/v1/requests \
  -H "X-City-Key: $COMPANY_PUBLIC_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"category_id": "<job type id from GET /public/v1/categories>",
       "lat": 36.7378, "lng": -119.7871, "address": "1420 W Olive Ave",
       "answers": {}, "contact": {"email": "[email protected]"},
       "language": "en", "source": "web"}'

# 201 Created
# {"number": 1342, "tracking_token": "…", "track_url": "…", "status": "Received"}

Verify a webhook signature (Python)

import hashlib, hmac, time

def verify(secret: str, headers: dict, raw_body: bytes) -> bool:
    ts = headers["X-Civic311-Timestamp"]
    signed = ts.encode() + b"." + raw_body          # "{timestamp}.{body}"
    expected = "sha256=" + hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
    if not hmac.compare_digest(expected, headers["X-Civic311-Signature"]):
        return False
    return abs(time.time() - int(ts)) < 300           # your choice: reject old deliveries

Read the full reference in the API docs.

Common questions

Where is the API reference?

The API serves interactive docs at /api/docs and the OpenAPI 3 file at /api/openapi.yaml, updated with every endpoint.

How does our website widget talk to Sentra Scheduler?

Through the public API, using your company’s public key. It lists your services, creates service requests with photos and looks up status by job number.

Do webhooks include customers’ personal data?

No. Payloads carry the job (number, job type, status, priority, team, assignee, address and location), not the customer’s name, email or phone. Each delivery is signed with HMAC SHA-256.

Is there an API key for server-to-server integrations?

No. Integrations use webhooks (Sentra Scheduler calls your system) and the REST API with a signed-in staff session.

Is single sign-on available?

No. Staff sign in with their own Sentra Scheduler accounts.