Migrating the User entity to 2026-10
Upgrade your monday.com integration to the new User entity shape introduced in API version 2026-07, and prepare for the legacy field removals scheduled for 2026-10.
Starting with API version 2026-07, the User type and Query.users gain new fields, types, enums, and arguments; a new top-level user_configs query; and enforced pagination on users. Several legacy fields on User are deprecated and are scheduled for removal in 2026-10 (confirm availability with introspection or release notes for the version you call).
This guide walks you through migrating an integration from the 2026-04 (or earlier) shape of the User entity to the 2026-10 shape.
All prerequisite requests must include the
API-Version: 2026-07header (or later) to see the new fields, types, and query arguments described below.
Quick checklist
Before you migrate, grep your codebase for:
photo_original,photo_thumb,photo_thumb_small,photo_tiny,photo_smallis_guest,is_admin,is_view_only,is_pending,enabledis_verified,join_dateencrypt_api_token,sign_up_product_kindusers(kind: ...),users(newest_first: ...),users(non_active: ...)users { ... }calls with nolimitargument (silent pagination cap of 200)users(emails: ...)where any element could benull- Reads of
User.birthdaythat parse it as aDate - Reads of
User.created_atthat parse it as aDate(no time component) - Reads of
User.utc_hours_diffthat assume it's an integer
Each hit has a replacement in the sections below.
🚨 Breaking changes
1. Photo fields → photo_url nested object
photo_url nested objectThe five flat photo fields are deprecated. Replace with the nested PhotoUrl object.
Before (2026-04):
query {
me {
photo_original
photo_small
photo_thumb
photo_thumb_small
photo_tiny
}
}After (2026-07+):
query {
me {
photo_url {
original
small
thumb
thumb_small
tiny
}
}
}photo_url is nullable (PhotoUrl). Each size is also nullable (String). Handle the case where the user has no uploaded photo.
2. Kind boolean flags → kind string
kind stringThe is_guest, is_admin, and is_view_only booleans are deprecated. Use the kind string field instead.
Before:
query { users { id is_admin is_guest is_view_only } }After:
query { users { id kind } }Value mapping:
| Before (boolean true) | After (kind value) |
|---|---|
is_admin: true | kind == "admin" |
is_guest: true | kind == "guest" |
is_view_only: true | kind == "view_only" |
Other kind values you may see: member, agent_member, portal, and several *_api_user variants (see the full UserKindFilter enum).
3. Status booleans → status enum
status enumis_pending and enabled are replaced by the status: UserStatus! field.
Before:
query { users { id enabled is_pending } }After:
query { users { id status } }| Before | After |
|---|---|
enabled: true, is_pending: false | status == ACTIVE |
enabled: false | status == INACTIVE |
is_pending: true | status == PENDING |
4. is_verified → is_email_confirmed
is_verified → is_email_confirmedSame semantics, new name, and the type tightens from Boolean to Boolean!.
Before:
query { me { is_verified } }After:
query { me { is_email_confirmed } }5. join_date → became_active_at
join_date → became_active_atjoin_date was a Date (YYYY-MM-DD). became_active_at is an ISO8601DateTime with full timestamp precision.
Before:
query { me { join_date } } # "2023-09-02"After:
query { me { became_active_at } } # "2023-09-02T13:22:48.000Z"If your code parses join_date as YYYY-MM-DD, slice the first 10 characters of became_active_at or parse with a full ISO 8601 parser.
6. Query.users argument rename: kind → user_kind
Query.users argument rename: kind → user_kindDeprecation, not removal. The legacy
kind,newest_first, andnon_activearguments (sections 6, 7, and 8) are deprecated onQuery.usersstarting in2026-07and are still deprecated — not removed — in2026-10. They continue to work at runtime, so existing queries will not fail schema validation. The schema carries@deprecatedannotations with replacement reasons, visible viaargs(includeDeprecated: true)or in IDE tooling. A firm removal version has not been announced; migrate off them now so you're ready when one is.
The legacy kind: UserKind argument (enum values all, guests, non_guests, non_pending) is deprecated in 2026-07 with deprecationReason: "Use user_kind instead.". Replace with user_kind: UserKindFilterInput.
Before:
query { users(kind: non_guests, limit: 200) { id name } }After:
query {
users(
user_kind: { not_in: [GUEST] }
limit: 200
) { id name }
}Migration mapping:
Legacy kind value | New user_kind |
|---|---|
all | omit the argument |
guests | { in: [GUEST] } |
non_guests | { not_in: [GUEST] } |
non_pending | (no direct equivalent — use status: [ACTIVE] instead) |
UserKindFilter supports both individual kinds (ADMIN, MEMBER, GUEST, VIEW_ONLY, AGENT_MEMBER, PORTAL) and the BASIC group (= admin + member + guest + view_only), plus API-user kinds. Use not_in to exclude values from an expanded in set.
7. Query.users argument: newest_first → sort
Query.users argument: newest_first → sortnewest_first is deprecated in 2026-07 with deprecationReason: "Use sort instead.". It still works at runtime.
Before:
query { users(newest_first: true, limit: 50) { id created_at } }After:
query {
users(
sort: [{ field: CREATED_AT, direction: DESC }]
limit: 50
) { id created_at }
}sort takes a list of UsersSortInput, so multi-field sorts are supported (CREATED_AT is currently the only field).
8. Query.users argument: non_active → status
Query.users argument: non_active → statusnon_active is deprecated in 2026-07 with deprecationReason: "Use status instead.". It still works at runtime.
Before:
query { users(non_active: true) { id } } # all non-active users
query { users(non_active: false) { id } } # (default) active + pendingAfter:
query { users(status: [INACTIVE]) { id } }
query { users(status: [ACTIVE, PENDING]) { id } } # (default if omitted)If status is omitted, the server defaults to [ACTIVE, PENDING] (same as the old non_active: false behavior).
9. Pagination is now enforced
Before 2026-07 | 2026-07 and later | |
|---|---|---|
users { ... } (no limit) | returned all users | returns 200 users |
users(limit: N) with N > 1000 | allowed | error: Limit exceeds the maximum allowed value of 1000. |
If your code assumed a single call returned the full roster, add explicit pagination:
Before:
query { users { id email } }After:
query GetAllUsers($page: Int!) {
users(
limit: 1000
page: $page
sort: [{ field: CREATED_AT, direction: ASC }]
) {
id
email
}
}Loop over page = 1, 2, 3, … until the returned array has fewer than limit items.
10. Query.users(emails:) non-null elements
Query.users(emails:) non-null elements[String] → [String!]. Ensure you don't pass null elements inside the emails array — validate input client-side before sending.
11. User scalar type changes (2026-07)
User scalar type changes (2026-07)| Field | 2026-04 type | 2026-07+ type |
|---|---|---|
birthday | Date | String |
created_at | Date | ISO8601DateTime! |
utc_hours_diff | Int | Float |
birthdaynow ships as aString. Treat it as a freeform string; the value is stillYYYY-MM-DDbut the schema no longer guarantees that.created_atnow includes a time component (2023-09-02T13:22:48.000Z). If you parse with aDate-only parser, truncate to 10 characters first.utc_hours_diffis aFloat. Fractional hours (for example,5.5,-3.5) can now appear.
✅ Non-breaking additions
You can adopt these at your own pace. They are only available from 2026-07 onward.
New User fields
User fieldsSafe to add to existing queries once you set the API-Version: 2026-07 (or later) header.
query {
me {
id
account_id # new
status # new: UserStatus enum
invitation_method # new: InvitationMethod enum
serial_number # new: Int, nullable
is_deleted # new: Boolean!
became_active_at # new: ISO8601DateTime
bb_visitor_id # new: ID!
is_email_confirmed # new: Boolean!
photo_url { original thumb }
user_config { kind role_id visibility }
}
}New user_configs query
user_configs queryquery {
user_configs {
kind
role_id
visibility
}
}Requires users:read and user authorization. Returns every user config for the account, sorted by role_id ascending. Optional filters: kinds: [String], visibility: String.
Migration by version
| You are on | Minimum target | Do this |
|---|---|---|
2025-10 or earlier | 2026-07 | Everything above plus the 2026-04 migration. |
2026-04 | 2026-07 | Apply sections 1–11 when you bump the API-Version header. |
2026-07 | 2026-10 | No new breaking changes for the user entity itself. Double-check that you've already removed the legacy fields listed in sections 1–5 — they are planned for hard removal in 2026-10. |
Testing your migration
- Set the version header:
API-Version: 2026-07(or2026-10). - Run your existing queries. The deprecated
kind,newest_first, andnon_activearguments still work, so queries using them won't fail — but codegen and IDE tooling will surface@deprecatedwarnings once you regenerate against the new schema. Migrate them per sections 6–8. - Add an explicit
limit+pageloop wherever you previously calledusers { ... }with no limit — the silent 200-row cap is the most common surprise in2026-07. - For clients generated from introspection, regenerate against
https://api.monday.com/v2/get_schema?version=2026-07. If your tooling supports it, passincludeDeprecated: trueso the deprecated args show up in the dump — the default endpoint omits them. - Confirm every hit from the Quick checklist is addressed before you roll out.
Updated about 4 hours ago
