Schools and Companies
Schools and companies are reference data that MLH uses across the platform to describe where people study and work — for example, the school on a user's profile. Most integrations read these records to look up or match an existing school or company by name, rather than creating new ones.
Both are standard REST resources. See Making requests for
pagination, filtering, expand, and error responses, and
Authentication for how to authenticate and request scopes.
Schools
A school is a university or other institution, with its name, web domain, country, and whether MLH has verified it.
Endpoints
| Method | Path | Does |
|---|---|---|
GET | /v4/schools | List schools |
GET | /v4/schools/{id} | Get one school |
POST | /v4/schools | Create a school |
{id} is the school's id.
Fields
These fields appear in a school response. On create (POST /v4/schools), you set
them in the request body.
| Field | Type | Read/write | Description | Example |
|---|---|---|---|---|
id | string | read-only | Unique identifier for the school. | "3f8b…" |
name | string | write | The institution's name. | "University of Waterloo" |
domain_name | string | write | The school's primary web domain, used to match email addresses to a school. | "uwaterloo.ca" |
country | string | write | The country the school is in. | "Canada" |
abbreviations | array of strings | write | Common short forms or acronyms for the school. | ["UW", "UWaterloo"] |
verified | boolean | write | Whether MLH has verified this school record. | true |
type | string | write | The kind of institution. | "university" |
created_at | integer | read-only | When the record was created, as a Unix timestamp (seconds). | 1755561600 |
updated_at | integer | read-only | When the record was last updated, as a Unix timestamp (seconds). | 1755648000 |
All writable fields are optional; provide the ones you have. In responses,
created_at and updated_at are Unix timestamps.
Filtering
GET /v4/schools supports these filters (see
Filtering for operator syntax):
name—[eq],[contains],[excludes],[similar]domain_name—[eq],[contains],[excludes]country—[eq],[contains],[excludes]verified—[eq]
Because user-entered school names vary ("MIT" vs. "Massachusetts Institute of
Technology"), use the [similar] fuzzy filter to match a name that isn't exact.
See [similar] in Making requests.
Scopes
Requests are authenticated with an OAuth 2.0 access token or a bearer JWT. Request only the scopes your integration needs — see Scopes.
Example
Find schools that fuzzily match a name:
GET /v4/schools?name[similar]=Waterloo&limit=10
Look up one school by its id:
GET /v4/schools/3f8b…
Companies
A company is an organization such as a sponsor or an employer, with its name, slug, and web domain.
Endpoints
| Method | Path | Does |
|---|---|---|
GET | /v4/companies | List companies |
GET | /v4/companies/{id} | Get one company |
POST | /v4/companies | Create a company |
PATCH / PUT | /v4/companies/{id} | Update a company |
{id} is the company's id. PATCH and PUT accept the same body; send the
fields you want to change.
Fields
These fields appear in a company response. On create and update, you set them in the request body.
| Field | Type | Read/write | Description | Example |
|---|---|---|---|---|
id | string | read-only | Unique identifier for the company. | "a91c…" |
name | string | write | The company's name. | "Acme Inc." |
slug | string | write | A URL-friendly identifier for the company. | "acme-inc" |
domain_name | string | write | The company's primary web domain. | "acme.com" |
created_at | integer | read-only | When the record was created, as a Unix timestamp (seconds). | 1755561600 |
updated_at | integer | read-only | When the record was last updated, as a Unix timestamp (seconds). | 1755648000 |
All writable fields are optional; provide the ones you have. In responses,
created_at and updated_at are Unix timestamps.
Filtering
GET /v4/companies supports these filters (see
Filtering for operator syntax):
name—[eq],[contains],[excludes],[similar]domain_name—[eq],[contains],[excludes]
As with schools, use the [similar] fuzzy filter on name to match a company
whose name isn't an exact string. See
[similar] in Making requests.
Scopes
Requests are authenticated with an OAuth 2.0 access token or a bearer JWT. Request only the scopes your integration needs — see Scopes.
Example
Search companies by partial name:
GET /v4/companies?name[contains]=acme&limit=10
Update a company's domain:
PATCH /v4/companies/a91c…
Content-Type: application/json
{
"domain_name": "acme.io"
}
Related
- V4 API overview
- Making requests — pagination, filtering,
expand, and errors. - Authentication — authentication methods and scopes.
- Users — user profiles that reference a school.