The Contacts API lets external systems read, create and update Newsroom contacts. Common uses: pushing new prospective family records from a CRM, syncing alumni data from an external system, reading subscription status for a finance system that needs to know who’s opted out of communications.
What the API does
Endpoints support:
- List contacts — paginated read of all contacts.
- Get a single contact — full record by ID or email.
- Create a contact — push a new contact into Newsroom.
- Update a contact — modify fields on an existing contact.
- Apply tags — add or remove tags.
- Subscription management — read or update subscription status.
- List membership — add/remove a contact from a list.
Authentication
The Contacts API requires an authenticated token. Generate the token in your PortalHQ admin settings under API tokens. Include it on every request:
Authorization: Token <your-token-here>
Tokens are tied to a specific user — the API call has the permissions of that user. Use a dedicated integration user for API access rather than a personal account, so audit logs are clear and the token can be rotated without affecting human users.
Common workflows
Pushing new contacts from a CRM
POST /newsroom/api/contacts/
{
"email": "parent@example.com",
"first_name": "Alice",
"last_name": "Example",
"custom_fields": {
"Year Group": "7",
"Source": "Open Day 2026"
},
"lists": ["prospective-parents"]
}
PortalHQ creates the contact and adds them to the Prospective Parents list immediately.
Updating subscription status
PATCH /newsroom/api/contacts/{id}/
{
"subscription_status": "unsubscribed"
}
For honouring an unsubscribe collected outside PortalHQ (e.g. via a paper form or a phone call).
Reading subscription status
GET /newsroom/api/contacts/{id}/
Returns the contact with current subscription status, tags and list memberships.
Bulk import
The bulk import endpoint accepts an array of contacts in one request:
POST /newsroom/api/contacts/bulk/
{
"contacts": [
{ "email": "...", "first_name": "...", ... },
...
]
}
Use this for migrations or large nightly syncs. The endpoint returns success/failure status per contact.
Best practices
Idempotency
Match contacts by email when creating. If a contact with the email already exists, the create endpoint updates it rather than creating a duplicate. This makes nightly sync scripts safe to re-run.
Source-of-truth discipline
Decide which system is the source of truth for each contact:
- SIS-sourced contacts (parents of current students) — the SIS is the source. Don’t push these via the Contacts API.
- External-sourced contacts (alumni, prospective families, vendors) — the external system is the source.
Pushing contacts via the API that are also managed by the SIS sync creates a tug-of-war. Each sync overwrites the other.
Respecting unsubscribes
If a contact has subscription_status = unsubscribed, do not push updates that include subscribed status without verifying explicit re-consent. The API will accept the update, but you’re now responsible for the legitimacy of the change.
Rate limits
The default rate limits suit most integrations. For high-volume syncs (large nightly imports), talk to PortalHQ support about elevated limits or batch endpoints.
Webhooks
For real-time integrations (e.g. update the CRM when a contact unsubscribes), use webhooks rather than polling:
- Register a webhook URL in PortalHQ settings.
- Pick the events to subscribe to (contact created, contact updated, contact unsubscribed).
- PortalHQ POSTs to your URL when each event happens.
Documentation
See the Swagger UI at /doc/swagger/ for the live API schema, endpoint parameters, request/response examples and the option to try requests against your school’s data.
Tips
- Use a dedicated API token for each integration. Easier to revoke if one is compromised.
- Log API requests at your consumer side so you can debug. PortalHQ also logs API requests but your own log is faster to inspect.
- Test in a sandbox first. Pushing 10,000 contacts to production by mistake is hard to undo.
- Respect privacy. Contact data is personal — applies the same care as other personal data, including GDPR/Privacy Act considerations if relevant.