Summary and recommendation
Vimeo's REST API authenticates via OAuth 2.0 and supports Authorization Code, Client Credentials, and Implicit grant types.
The base URL is https://api.vimeo.com.
Scope selection is consequential: the `private` scope is required to read a user's email address, and Client Credentials tokens are app-level only - they cannot access user-private data.
Use Authorization Code flow for any user-delegated operation.
Rate limits are enforced per app and vary by API tier: 250 requests per 15 minutes for free/basic apps, 1,000 for apps tied to paid Vimeo accounts, and custom limits at Enterprise.
All responses carry `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` headers.
HTTP 429 is returned on breach;
use the `X-RateLimit-Reset` Unix timestamp to determine window reset - no `Retry-After` header is documented.
Pagination is offset-based using `page` and `per_page` parameters, with a maximum `per_page` of 100.
For identity graph construction across large user sets, plan for multi-page iteration and rate limit headroom accordingly.
API quick reference
| Has user API | Yes |
| Auth method | OAuth 2.0 (Authorization Code, Client Credentials, Implicit flows) |
| Base URL | Official docs |
| SCIM available | Yes |
| SCIM plan required | Enterprise |
Authentication
Auth method: OAuth 2.0 (Authorization Code, Client Credentials, Implicit flows)
Setup steps
- Register an application at https://developer.vimeo.com/apps/new to obtain a client_id and client_secret.
- Choose an OAuth 2.0 grant type: Authorization Code (user-delegated), Client Credentials (app-level), or Implicit.
- Request the required scopes during the authorization request.
- Exchange the authorization code (or use client credentials) for an access token via POST https://api.vimeo.com/oauth/access_token.
- Include the access token in all API requests as: Authorization: bearer {token}.
Required scopes
| Scope | Description | Required for |
|---|---|---|
| public | Read public user data. | GET /users/{user_id} (public profile) |
| private | Read private user data including email address. | GET /me, reading authenticated user's private fields |
| edit | Edit user account data and settings. | PATCH /users/{user_id}, updating user profile |
| upload | Upload videos on behalf of the user. | POST /users/{user_id}/videos |
| video_files | Access video file download links. | Retrieving download URLs for video files |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| uri | string | The user's canonical API URI, e.g. /users/12345. | system-assigned | immutable | Use as stable identifier. |
| name | string | Display name of the user. | required | editable | |
| link | string | URL of the user's Vimeo profile page. | system-assigned | immutable | |
| location | string | User's self-reported location. | optional | editable | |
| bio | string | User's biography text. | optional | editable | |
| short_bio | string | Shortened biography. | optional | editable | |
| created_time | string (ISO 8601) | Timestamp when the account was created. | system-assigned | immutable | |
| account | string (enum) | Account plan type: basic, plus, pro, business, live_premium, enterprise. | system-assigned | immutable via API | Reflects billing plan; not directly settable via API. |
| string | User's email address. Requires 'private' scope. | required | editable | Only returned when authenticated with private scope. | |
| pictures | object | Profile picture sizes and URIs. | system-assigned | editable via separate endpoint | |
| websites | array | List of user's linked websites. | optional | editable | |
| metadata.connections.videos | object | Connection object with total video count and URI. | system-assigned | immutable | |
| metadata.connections.followers | object | Connection object with follower count and URI. | system-assigned | immutable | |
| metadata.connections.following | object | Connection object with following count and URI. | system-assigned | immutable | |
| upload_quota | object | Storage quota details: space used, free, max, and type. | system-assigned | immutable via API | Reflects plan limits. |
| preferences | object | User preferences including video privacy defaults. | optional | editable | |
| content_filter | array | Content rating filters applied to the user's feed. | optional | editable |
Core endpoints
Get authenticated user
- Method: GET
- URL:
https://api.vimeo.com/me - Watch out for: Email is only returned when the token has the 'private' scope.
Request example
GET /me
Authorization: bearer {token}
Response example
{
"uri": "/users/12345",
"name": "Jane Doe",
"email": "jane@example.com",
"account": "pro",
"created_time": "2020-01-15T10:00:00+00:00"
}
Get user by ID
- Method: GET
- URL:
https://api.vimeo.com/users/{user_id} - Watch out for: Private fields (email) are not returned unless the token belongs to that user with 'private' scope.
Request example
GET /users/12345
Authorization: bearer {token}
Response example
{
"uri": "/users/12345",
"name": "Jane Doe",
"link": "https://vimeo.com/janedoe",
"account": "pro"
}
Edit authenticated user
- Method: PATCH
- URL:
https://api.vimeo.com/me - Watch out for: Requires 'edit' scope. Only the authenticated user can edit their own profile via /me.
Request example
PATCH /me
Authorization: bearer {token}
Content-Type: application/json
{"name": "Jane Smith", "bio": "Video creator."}
Response example
{
"uri": "/users/12345",
"name": "Jane Smith",
"bio": "Video creator."
}
List user's videos
- Method: GET
- URL:
https://api.vimeo.com/users/{user_id}/videos - Watch out for: Private videos are only returned when the token belongs to the video owner.
Request example
GET /users/12345/videos?page=1&per_page=25
Authorization: bearer {token}
Response example
{
"total": 42,
"page": 1,
"per_page": 25,
"data": [{"uri": "/videos/98765", "name": "My Video"}]
}
List followers of a user
- Method: GET
- URL:
https://api.vimeo.com/users/{user_id}/followers - Watch out for: Returns public follower list; no private data exposed.
Request example
GET /users/12345/followers?page=1&per_page=25
Authorization: bearer {token}
Response example
{
"total": 100,
"data": [{"uri": "/users/67890", "name": "Follower Name"}]
}
Follow a user
- Method: PUT
- URL:
https://api.vimeo.com/me/following/{follow_user_id} - Watch out for: Requires 'interact' scope. Returns 204 on success with no body.
Request example
PUT /me/following/67890
Authorization: bearer {token}
Response example
HTTP 204 No Content
Unfollow a user
- Method: DELETE
- URL:
https://api.vimeo.com/me/following/{follow_user_id} - Watch out for: Requires 'interact' scope.
Request example
DELETE /me/following/67890
Authorization: bearer {token}
Response example
HTTP 204 No Content
Search users
- Method: GET
- URL:
https://api.vimeo.com/users - Watch out for: Only public profiles are returned. Results are limited by Vimeo's search index.
Request example
GET /users?query=janedoe&page=1&per_page=10
Authorization: bearer {token}
Response example
{
"total": 5,
"data": [{"uri": "/users/12345", "name": "Jane Doe"}]
}
Rate limits, pagination, and events
- Rate limits: Vimeo enforces per-app rate limits that vary by API plan tier. Limits are communicated via response headers on each request.
- Rate-limit headers: Yes
- Retry-After header: No
- Rate-limit notes: The API returns X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers. When the limit is exceeded, the API returns HTTP 429. No Retry-After header is explicitly documented; use X-RateLimit-Reset (Unix timestamp) to determine when the window resets.
- Pagination method: offset
- Default page size: 25
- Max page size: 100
- Pagination pointer: page / per_page
| Plan | Limit | Concurrent |
|---|---|---|
| Free / Basic app | 250 requests per 15 minutes (per app) | 0 |
| Authenticated (paid Vimeo account) | 1000 requests per 15 minutes (per app) | 0 |
| High-volume / Enterprise API | Custom – negotiated with Vimeo | 0 |
- Webhooks available: No
- Webhook notes: Vimeo does not offer a general-purpose webhook system for user management events via the public API. Video-related event callbacks (e.g., transcode completion) are available via the API but are scoped to video lifecycle, not user account changes.
- Alternative event strategy: Poll GET /me or relevant user endpoints for state changes. For enterprise provisioning events, use SCIM with Okta or Azure AD which handles provisioning/deprovisioning lifecycle.
SCIM API status
SCIM available: Yes
SCIM version: 2.0
Plan required: Enterprise
Endpoint: Provisioned by the IdP (Okta or Azure AD) during SCIM app configuration in Vimeo's SSO settings. The tenant-specific SCIM base URL is generated within the Vimeo Enterprise admin panel under SSO/SCIM settings.
Supported operations: Create user (POST /Users), Read user (GET /Users/{id}), Update user (PATCH /Users/{id}), Deactivate/deprovision user (PATCH /Users/{id} with active=false), List users (GET /Users)
Limitations:
- SCIM is only available on the Enterprise plan.
- SSO (SAML) must be configured as a prerequisite before enabling SCIM.
- Supported IdPs are Okta and Azure AD (Entra ID) only; Google Workspace and OneLogin are not officially supported.
- Group provisioning support is not explicitly documented in official help articles.
- The SCIM endpoint URL is tenant-specific and generated inside the Vimeo admin UI; it is not a static public endpoint.
Common scenarios
Three integration patterns cover the majority of Vimeo API use cases for identity and access workflows.
For authenticated user profile resolution: obtain an Authorization Code token with private scope, call GET /me, and read the account field for plan tier, email for identity graph linkage, and upload_quota.space.free for storage state.
If the token lacks private scope, the email field is silently absent - not an error, just missing.
For Enterprise SCIM provisioning via Okta: SAML SSO must be fully configured in the Vimeo admin panel before SCIM can be enabled.
The tenant-specific SCIM base URL and bearer token are generated inside the Vimeo admin UI this bearer token is distinct from OAuth tokens and must be updated in Okta separately if rotated.
Deprovisioning is handled by unassigning the user in Okta, which sends PATCH /Users/{id} with active=false.
For video library pagination: use GET /users/{user_id}/videos?page=1&per_page=100, read the total field to calculate page count, and iterate.
Monitor X-RateLimit-Remaining on each response;
free-tier apps will exhaust limits quickly on large libraries.
Fetch authenticated user profile and check plan
- Obtain an OAuth 2.0 access token via Authorization Code flow with 'private' scope.
- GET https://api.vimeo.com/me with Authorization: bearer {token}.
- Read the 'account' field to determine the user's plan (e.g., 'enterprise', 'pro').
- Read the 'email' field (available because 'private' scope was granted).
- Read 'upload_quota.space.free' to check remaining storage.
Watch out for: If the token was issued without 'private' scope, the 'email' field will be absent from the response.
Provision Enterprise users via SCIM with Okta
- Confirm the Vimeo account is on the Enterprise plan.
- Configure SAML SSO in the Vimeo Enterprise admin panel first (prerequisite).
- Navigate to the SCIM settings section in the Vimeo admin panel to retrieve the tenant SCIM base URL and bearer token.
- In Okta, add the Vimeo SCIM application and enter the SCIM base URL and bearer token.
- Assign users or groups in Okta to the Vimeo SCIM app; Okta will POST /Users to provision accounts.
- To deprovision, unassign the user in Okta; Okta sends PATCH /Users/{id} with active=false.
Watch out for: The SCIM bearer token is generated by Vimeo and is distinct from OAuth tokens. Rotating it requires updating the Okta app configuration.
Paginate through all videos for a user
- Obtain an OAuth 2.0 access token with at minimum 'public' scope (or 'private' for private videos).
- GET https://api.vimeo.com/users/{user_id}/videos?page=1&per_page=100.
- Read the 'total' field from the response to calculate total pages (ceil(total / per_page)).
- Increment the 'page' parameter and repeat until all pages are retrieved.
- Monitor X-RateLimit-Remaining header; back off if approaching the limit.
Watch out for: per_page maximum is 100. For users with large libraries, many requests may be needed; rate limits apply per app across all users.
Why building this yourself is a trap
The Vimeo API does not offer webhooks for user management events. There is no push notification when a user is created, deactivated, or has their role changed - video transcode callbacks exist, but they are scoped to video lifecycle only.
Any identity graph that depends on Vimeo user state must be maintained through polling GET /me or user endpoints, which consumes rate limit budget continuously.
SCIM is the only supported path for automated provisioning lifecycle, and it is hard-gated: Enterprise plan required, SAML SSO must be active first, and only Okta and Azure AD (Entra ID) are officially supported IdPs. Google Workspace and OneLogin are not documented. Group provisioning support via SCIM is also not explicitly confirmed in official documentation.
For teams building an identity graph that includes Vimeo, the practical constraint is this: below Enterprise, there is no programmatic way to provision or deprovision team members - the API exposes user profile data but provides no team membership write operations outside of SCIM. Architect accordingly.
Automate Vimeo workflows without one-off scripts
Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.