TeamzHQ is in preview. Try the demo company and tell us what you think.
TeamzHQ

API and integrations

Connect TeamzHQ to the systems you already run

An open REST API, signed webhooks, HR and ERP connectors, single sign on, calendar sync, and CSV in and out. Workspace owners manage all of it from Integrations.

HR and ERP systems

Built in connectors for Odoo, SAP SuccessFactors, Oracle HCM, Microsoft Dynamics 365 and Sage HR. Any other system can push people in through the API.

Single sign on

Staff sign in with their Google Workspace or Microsoft 365 account, or with a one time email link.

Calendar sync

Every person gets a private calendar address. One on ones and interviews appear in Google Calendar, Outlook or Apple Calendar and stay up to date.

CSV import and export

Bring people in from any spreadsheet or HR export. Export people and review results for payroll.

Open API

List and update employees, jobs, applications, goals and released review results.

Webhooks

Get told the moment someone applies, moves stage, joins, completes a goal or gets their review.

Connecting an HR or ERP system

There are two ways to keep people in TeamzHQ in step with the system of record. Pick whichever suits the client's IT team. Both feed the same sync, so they can be mixed.

1. TeamzHQ reads from your system

A workspace owner enters the system's credentials in Integrations, tests the connection, checks the preview, then syncs. Field mapping can be adjusted on screen when a client has renamed or custom fields. Credentials are encrypted at rest.

2. Your system pushes to TeamzHQ

Your integration tool sends people to POST /api/v1/employees on a schedule or when a record changes. No credentials for your system ever leave your side. Use this for any platform, including ones without a built in connector.

SystemWhat TeamzHQ needs to read from itHow to push from it instead
SAP SuccessFactorsAPI server, company ID, an OAuth client registered with an X.509 certificate (client ID and private key), and an API user that can read User data.Integration Center: a scheduled integration with a REST destination that posts JSON to /api/v1/employees. Or an SAP Integration Suite flow with an HTTP receiver.
Oracle HCM CloudPod address, plus an integration user and password with a role that can read workers.Oracle Integration Cloud: the HCM adapter as the trigger, a REST adapter calling /api/v1/employees. Or a scheduled HCM Extract to CSV and the CSV import.
Microsoft Dynamics 365Environment address, tenant ID, and an Entra ID app (client ID and secret) added in Dynamics with read access to workers.Power Automate: a scheduled or row changed trigger and an HTTP action posting to /api/v1/employees. Or a business event to Azure Logic Apps.
Sage HRThe company subdomain and an API key from Settings, Integrations.An automation tool such as Make or Zapier reading Sage HR employees and calling the API, or a CSV export.
Sage Business Cloud People, Sage 300, X3No direct connector. Push from your side.Scheduled employee export to CSV, or an integration tool calling the API.
OdooOdoo address, database, login email and an API key.An automated action that calls the API, though the built in connector is simpler.
Workday, BambooHR, Personio, payroll tools, spreadsheetsNo direct connector. Push from your side.Workday Studio or EIB, the vendor's webhooks, Make, Zapier, n8n, or a CSV file.

Employee fields

Send these in each employee object. Only email and full_name are required. Common alternative names such as work_email, employee_number, personnel_number, hire_date and manager_employee_id are accepted too.

emailWork email. Used to match people when there is no external_id, and to link their TeamzHQ sign in.
full_nameOr first_name and last_name.
external_idThe person's ID in your system. Strongly recommended: it keeps the match stable when emails change.
job_title, department, levelFree text, up to 120 characters each.
start_dateYYYY-MM-DD.
manager_external_id or manager_emailLinks the reporting line. The manager can arrive in the same request, in any order.
statusactive, or left (inactive, terminated and resigned also count as left). People who leave keep their history.

A typical nightly sync

  1. Create a write key in Integrations for the integration tool.
  2. Read everyone changed since the last run from your HR system.
  3. Send them in batches of up to 500 to POST /api/v1/employees, with external_id set. Existing people are updated, new ones created.
  4. Send leavers with status left rather than deleting them.
  5. Read the errors list in the response and log it. A 422 means nothing in the batch could be saved.

Sending results back

Subscribe a webhook to review.released, then call GET /api/v1/reviews?cycle_id=… to pull final ratings into payroll or compensation planning. employee.created and employee.updated tell your systems when someone joins through TeamzHQ, for example after a hire from the ATS.

Authentication

Create a key in Integrations. Send it as a bearer token. Read keys can list; write keys can also create and update employees. Keys are shown once and stored only as a hash.

curl https://teamzhq.vercel.app/api/v1/employees?status=active \
  -H "Authorization: Bearer tzhq_xxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Endpoints

GET/api/v1/employeesList people. Filters: status, updated_since. Paged with limit and cursor.
POST/api/v1/employeesCreate or update up to 500 people, matched on external_id then email.
GET/api/v1/employees/{id}One person.
PATCH/api/v1/employees/{id}Change title, department, level, manager, status and more.
GET/api/v1/jobsJobs. Filter: status.
GET/api/v1/applicationsCandidates in the pipeline with stage and AI fit. Filters: job_id, stage.
GET/api/v1/goalsGoals and progress. Filters: employee_id, company.
GET/api/v1/reviewsReleased review cycles, and final ratings per person with cycle_id.
curl -X POST https://teamzhq.vercel.app/api/v1/employees \
  -H "Authorization: Bearer tzhq_..." -H "Content-Type: application/json" \
  -d '{"employees":[{"email":"ada@acme.com","full_name":"Ada Obi","job_title":"Analyst",
       "department":"Finance","external_id":"EMP001","manager_email":"boss@acme.com"}]}'

Webhooks

  • employee.created · A person is added
  • employee.updated · A person's details change
  • application.created · Someone applies for a job
  • application.stage_changed · A candidate moves stage
  • goal.completed · A goal is completed
  • review.released · A review cycle is released

Each delivery is a JSON POST signed with your endpoint secret. Check the signature before you trust it:

// Node.js
import { createHmac, timingSafeEqual } from "node:crypto";
const [t, v1] = req.headers["teamzhq-signature"].split(",").map(p => p.split("=")[1]);
const expected = createHmac("sha256", process.env.TEAMZHQ_WEBHOOK_SECRET).update(`${t}.${rawBody}`).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300;
const valid = fresh && timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
Feedback