Skip to main content

sayhii Organization API

The sayhii Organization API helps you keep your employee data and shared dictionaries in sync—so your people always have access to the latest information, without manual uploads or spreadsheet wrangling.

Base URL: https://connect.sayhii.io
Authorization Header: Authorization: ApiKey <key>
Org Context: The API key itself determines your organization.

tip

Only customer admins can create API keys. Share keys only with trusted developers or services, and scope them appropriately. API Keys can be managed in the sayhii Portal, for more information see API Keys

info

The sayhii Organization API is not available to all Organizations by default. Get in touch with us if you are interested in using the API to keep your employee data up to date in sayhii.

Quick Start

Sync your user list in just a few lines of code:

curl -H "Authorization: ApiKey $API_KEY" https://connect.sayhii.io/users

Users

The Users endpoints let you retrieve employee information from sayhii, so you can see who is already loaded and configured in sayhii.

GET /users

Get a paginated list of everyone in your organization.

Query Parameters

  • limit (number, optional): Maximum number of users to return in this response.
  • nextToken (string, optional): Token for retrieving the next page of results (returned by a previous call).

Response

Returns a JSON object:

  • users (UserSchema[], required): Array of user objects (length ≤ limit).
  • nextToken (string, optional): Token for retrieving the next page (pass as a parameter to the next API call). Omitted if there are no more results.

Notes

  • Sort Order: The order of users is not guaranteed—do not rely on array order.
  • Use limit and nextToken for efficient pagination through large user lists.
  • If you don’t provide a limit, the API will return as many users as possible in a single response (up to a maximum payload size of 300MB). If there are more users, you’ll get a nextToken to fetch the next batch.
tip

For large organizations, always use pagination to avoid timeouts and keep your integration reliable.

Example

curl -H "Authorization: ApiKey $API_KEY" "https://connect.sayhii.io/users?limit=100"

POST /users

Add or update users in batch upsert mode—perfect for syncing your HRIS or directory.

  • Body: Array of UserSchema objects
  • Matching Logic:
    • Match on email first → update attributes.
    • If email doesn’t match but id does → treat as a new record with the new email (old record replaced).
  • Batch Size: Recommend ≤ 100,000 users (~200 MB) for reliability.
  • Responses:
    • 200 – All records processed successfully
    • 210 – Partial success (check errors[])
    • 400, 401, 500, 502 – Error

Example

curl -X POST -H "Authorization: ApiKey $API_KEY" \
-H "Content-Type: application/json" \
-d '[{
"id": "123",
"email": "jane@example.com",
"firstName": "Jane",
"lastName": "Doe",
"department": "Marketing"
}]' \
https://connect.sayhii.io/users

Partial Failure Response

{
"successCount": 9,
"failureCount": 1,
"message": "Processed with some errors",
"errors": [
{
"userId": "456",
"error": "Invalid department value"
}
]
}
info

Values for dictionary‑controlled user attributes (department, jobFunction, workType, role, gender, race, ethnicity) must match an existing dictionary entry. If any value is not recognized, that user record is rejected and an error is returned. To introduce a new value, update the appropriate dictionary first (via PUT /dictionaries or PATCH /dictionaries). See the UserSchema and DictionarySchema sections for definitions and examples.

GET /users/{id}

Look up a single user by their id (not email).

  • Path Parameter: id – The unique identifier you provided as id.
  • Response: Single user object (UserSchema)
curl -H "Authorization: ApiKey $API_KEY" https://connect.sayhii.io/users/123

Dictionaries

Dictionaries define the valid values for job functions, departments, work types, and similar fields—helping you keep your data clean and consistent. They also control which options users see when registering through the sayhii app, if your organization has enabled self-registration.

GET /dictionaries

Retrieve the full DictionarySchema. All keys are always present—missing values are filled with defaults.

curl -H "Authorization: ApiKey $API_KEY" https://connect.sayhii.io/dictionaries

GET /dictionaries/{dictionaryType}

Retrieve values for a single dictionary.

  • Valid Types: jobFunction, role, gender, race, ethnicity, workType, department
curl -H "Authorization: ApiKey $API_KEY" https://connect.sayhii.io/dictionaries/department

PUT /dictionaries

Replace dictionaries with a new set of values.

curl -X PUT -H "Authorization: ApiKey $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "department": ["Marketing","Sales","Engineering"] }' \
https://connect.sayhii.io/dictionaries

This example replaces every dictionary: because only department values are provided, all other dictionaries revert to their defaults while department is set to the custom list you supplied.

PATCH /dictionaries

Merge new values by replacing only the provided keys.

curl -X PATCH -H "Authorization: ApiKey $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "role": ["User","Admin","Manager"] }' \
https://connect.sayhii.io/dictionaries

This PATCH updates only the role dictionary; every other dictionary keeps its previously defined values (whether default or custom) unchanged.

warning

Only admins with appropriately scoped API keys can modify dictionaries or users.


Schemas

UserSchema

FieldTypeRequiredNotes
idstringUnique per org. Use your backend’s stable identifier.
emailstringCase-insensitive. Must be unique.
firstNamestringOptional.
lastNamestringOptional.
departmentstringMust match a dictionary value.
jobFunctionstringMust match a dictionary value.
workTypestringMust match a dictionary value.
rolestringMust match a dictionary value.
managerEmailstringAuthoritative for hierarchy.
managerGuidstringOptional reference if manager email changes.
guidstringOptional reference for your backend system.
hireYearAndMonthstringFormat YYYY.MM.
yearOfBirthstringFour-digit year.
terminatedstring'Y' or 'N' (default 'N').
disabledbooleanCan be toggled by POST. Default false.
portalQuestionsbooleanWhether user can answer in portal. Default false.
workingZipCodestringOptional.
race/ethnicity/genderstringMust match dictionary values.

DictionarySchema

Each key contains an array of valid strings:

KeyExample Values
jobFunction["Engineering","Marketing"]
role["User","Admin","Manager"]
gender["Male","Female","Non-binary"]
race["Asian","White","Black"]
ethnicity["Hispanic","Non-Hispanic"]
workType["Remote","Hybrid","Onsite"]
department["Sales","HR","Product"]

Errors

RequestError

FieldTypeDescription
messagestringHuman-readable description.
detailsstringAdditional error details (optional)
stackstringDebug information (optional)

Common Status Codes

CodeMeaning
200Success
210Partial success (check errors)
400Bad request
401Unauthorized (invalid API key)
404Not found
500Internal server error
502Upstream error

Best Practices

  • Batch Size: Keep requests ≤ 100,000 users (~200 MB) for reliability.
  • Avoid PHI: Do not send protected health information.
  • Case-Insensitive Emails: Emails are lowercased for matching.
  • Retries: Use exponential backoff for 5xx/502 responses.
  • Security: Provide keys only to trusted parties. Keys are org-scoped.

Changelog & Support

The API does not use versioned paths today. Breaking changes will be announced with advance notice.

For help or questions: support@sayhii.io