You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This PR tracks the ongoing progress of migrating Rocket.Chat API endpoints to the new OpenAPI pattern with AJV validation and improved documentation. It will be continuously updated to reflect completed and remaining work.
✅ Summary
Total endpoints: XX
Migrated so far: 53
Remaining: XX
👥 Team
Ahmed Nasser – Contributor
Matheus Cardoso – Mentor
Guilherme Gazzo – Co-mentor
🚨 Core API Endpoints
These are 500 endpoints critical for core features and should be migrated first:
Endpoints type is augmented in apps/meteor, but packages/ddp-client can’t see it because they have separate TypeScript compilation contexts.
need a shared .d.ts type declaration (or project references) so both projects see the same augmentation without importing Meteor code
Endpoints type is augmented in apps/meteor, but packages/ddp-client can’t see it because they have separate TypeScript compilation contexts.
need a shared .d.ts type declaration (or project references) so both projects see the same augmentation without importing Meteor code
Endpoints type is augmented in apps/meteor, but packages/ddp-client can’t see it because they have separate TypeScript compilation contexts.
need a shared .d.ts type declaration (or project references) so both projects see the same augmentation without importing Meteor code
Endpoints type is augmented in apps/meteor, but packages/ddp-client can’t see it because they have separate TypeScript compilation contexts.
need a shared .d.ts type declaration (or project references) so both projects see the same augmentation without importing Meteor code
⛔ Typia generates oneOf when it encounters a union type (|) in the interface.
The issue with oneOf is that it requires exactly one schema to match—similar to XOR logic—so overlapping types fail validation.
To fix this, we need Typia to generate anyOf instead of oneOf.
⛔ Typia generates oneOf when it encounters a union type (|) in the interface.
The issue with oneOf is that it requires exactly one schema to match—similar to XOR logic—so overlapping types fail validation.
To fix this, we need Typia to generate anyOf instead of oneOf.
⛔ Typia generates oneOf when it encounters a union type (|) in the interface.
The issue with oneOf is that it requires exactly one schema to match—similar to XOR logic—so overlapping types fail validation.
To fix this, we need Typia to generate anyOf instead of oneOf.
When migrating endpoints to the new OpenAPI + AJV pattern, keep these points in mind:
No Change in Logic
The migration should only update the structure, validation, and documentation.
The core business logic, permissions, and side effects must remain exactly the same
Error Response Codes
400 (Bad Request) → Should be included for most endpoints with input validation.
401 (Unauthorized) → Add only if the endpoint authRequired: true is included.
403 (Forbidden) → Add only if specific permission checks are performed.
Schema Validation
Use AJV for request/response validation.
Use Typia-generated$ref schemas where available instead of manually defining large object shapes.
Centralized Error Validators
Use shared helpers like validateBadRequestErrorResponse instead of hard-coding error schemas.
This keeps error formats consistent across all endpoints.
Route Definition Style
Use Route Method Chaining when defining multiple methods (.post(), .get(), etc.).
This is possible because ExtractRoutesFromAPI automatically groups routes under the same path in the type definitions.
Optional Properties
If an endpoint doesn’t need permissionsRequired, omit it.
Always explicitly declare query or body in the route options — even if the endpoint has no parameters, set it to query: undefined or body: undefined.
Keep configs minimal — only include what’s necessary for that endpoint.
No More rest-typings or Manual Typings
All request/response schemas are now defined directly inside the route definition file.
No schema definitions in rest-typings or other manual typing files — everything for an endpoint lives in one place for easier maintenance.
Swagger Documentation
Confirm that both request and response schemas appear correctly in Swagger UI.
Check that example values are meaningful and match real data structures.
📖 Example: Migrating from Old Pattern to New Pattern
This example shows how to migrate from the legacy addRoute approach (with manual typings and deprecated validation)
to the new typed API definition pattern using:
API.v1.post() / .get() chaining (so multiple HTTP methods for the same path are merged in typings)
AJV for request & response validation
Typia $ref for shared model schemas
Automatic route typings with ExtractRoutesFromAPI (no more manual duplication)
Predefined error response validators instead of hard-coded schemas
constbazEndpoints=API.v1// POST /v1/baz.foo.post('baz.foo',{authRequired: true,body: ajv.compile<{name: string}>({type: 'object',properties: {name: {type: 'string'}},required: ['name'],additionalProperties: false,}),permissionsRequired: ['manage-foo'],response: {400: validateBadRequestErrorResponse,// Common for validation errors// 401: validateUnauthorizedErrorResponse, // Optional: if endpoint used with auth// 403: validateForbiddenErrorResponse, // Optional: if specific permission checks exist200: ajv.compile<{foo: IBaz}>({type: 'object',properties: {foo: {$ref: '#/components/schemas/IBaz'},// ✅ Typia model reusesuccess: {type: 'boolean',enum: [true]},},required: ['foo','success'],additionalProperties: false,}),},},asyncfunctionaction(){constresult=awaitupdateFoo(this.bodyParams);returnAPI.v1.success(result);},)// GET /v1/baz.bar.get('baz.bar',{authRequired: true,query: ajv.compile<{name: string}>({type: 'object',properties: {name: {type: 'string'}},required: ['name'],additionalProperties: false,}),permissionsRequired: ['manage-bar'],response: {400: validateBadRequestErrorResponse,// 401: validateUnauthorizedErrorResponse, // Optional// 403: validateForbiddenErrorResponse, // Optional200: ajv.compile<{foo: IBaz}>({type: 'object',properties: {bar: {$ref: '#/components/schemas/IBaz'},success: {type: 'boolean',enum: [true]},},required: ['bar','success'],additionalProperties: false,}),},},asyncfunctionaction(){returnAPI.v1.success(awaitgetBar(this.queryParams.name));},);// ✅ Automatically generate typings for both GET and POST without duplicationexporttypeBazEndpoints=ExtractRoutesFromAPI<typeofbazEndpoints>;declare module '@rocket.chat/rest-typings'{// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-empty-interfaceinterfaceEndpointsextendsBazEndpoints{}}
Key Improvements in the New Pattern
Single source of truth for typings ExtractRoutesFromAPI pulls types directly from your post() / get() definitions — no more manual edits in rest-typings.
Strong request validation with AJV
Both body (POST) and query (GET) are validated against JSON schemas.
Strong response validation
Ensures the API always returns objects that match the documented shape.
Reusable schemas with Typia $ref: '#/components/schemas/IBaz' links to a single IBaz schema used across APIs.
Chaining multiple methods on the same path
Calling .post().get() on the same fooEndpoints ensures both methods are merged into one entry in the generated Endpoints interface.
🧪 Testing Plan
Ensure all migrated endpoints validate request and response schemas using AJV.
Confirm accurate documentation in Swagger UI for each endpoint.
Run integration tests to avoid regressions.
💡 Notes
This PR is for tracking and visibility; implementation PRs will be linked progressively.
Please feel free to suggest changes to prioritization.
Hi @ahmed-n-abdeltwab I’d like to migrate the statistics.list endpoint to the new OpenAPI + AJV pattern. Please mark it as claimed.
I’ve submitted a PR for the statistics.list endpoint. Please pick one that hasn't been mentioned by someone else so we don't duplicate the work. There are enough APIs for everyone, and we want to avoid overlapping on the same PRs.
Hi @ahmed-n-abdeltwab I’d like to migrate the statistics.list endpoint to the new OpenAPI + AJV pattern. Please mark it as claimed.
I’ve submitted a PR for the statistics.list endpoint. Please pick one that hasn't been mentioned by someone else so we don't duplicate the work. There are enough APIs for everyone, and we want to avoid overlapping on the same PRs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
OpenAPI Migration Progress
This PR tracks the ongoing progress of migrating
Rocket.Chat APIendpoints to the new OpenAPI pattern with AJV validation and improved documentation. It will be continuously updated to reflect completed and remaining work.✅ Summary
👥 Team
🚨 Core API Endpoints
These are 500 endpoints critical for core features and should be migrated first:
Authentication (0 / 9 completed)
Content Management (2 / 11 completed)
emoji-custom.createchore: Add OpenAPI Support to emoji-custom.create API Rocket.Chat#36523custom-user-status.listchore: Add OpenAPI Support to custom-user-status.list API Rocket.Chat#36916Integrations (7 / 13 completed)
webdav.getMyAccountsfeat: Add OpenAPI Support to Webdav API Rocket.Chat#35884webdav.removeWebdavAccountfeat: Add OpenAPI Support to Webdav API Rocket.Chat#35884oauth-apps.createfeat: Add OpenAPI Support to oauth-apps.create API Rocket.Chat#36507oauth-apps.updatefeat: Add OpenAPI Support to oauth-apps.update API Rocket.Chat#36585oauth-apps.listfeat: Add OpenAPI Support to oauth-apps.list API Rocket.Chat#36586oauth-apps.getfeat: Add OpenAPI Support to oauth-apps.get API Rocket.Chat#36598oauth-apps.deletefeat: Add OpenAPI Support to oauth-apps.delete API Rocket.Chat#36606Marketplace Apps (0 / 4 completed)
Messaging (4 / 39 completed)
chat.pinMessagefeat: Add OpenAPI Support to chat.pinMessage API Rocket.Chat#36020chat.unPinMessagefeat: Add OpenAPI Support to chat.unpinMessage API Rocket.Chat#36668dm.closechore: Add OpenAPI Support to dm.close/im.close API Rocket.Chat#38974dm.deletefeat: Add OpenAPI Support to dm.delete/im.delete API Rocket.Chat#36677Omnichannel (0 / 154 completed)
Miscellaneous (2 / 24 completed)
autotranslate.translateMessagechore: Add OpenAPI support for the Rocket.Chat autotranslate translateMessage API Rocket.Chat#38978commands.getchore: Add OpenAPI Support to commands.get API Rocket.Chat#36953Notifications (0 / 6 completed)
Rooms (2 / 127 completed)
rooms.leavechore: migrate rooms.leave endpoint to new OpenAPI pattern with AJV validation Rocket.Chat#38957rooms.favoritechore: Add OpenAPI Support to rooms.favorite API Rocket.Chat#35995Settings (2 / 47 completed)
e2e.getUsersOfRoomWithoutKeychore: Add OpenAPI Support to e2e.getUsersOfRoomWithoutKey API Rocket.Chat#36786e2e.setRoomKeyIDfeat: Add OpenAPI Support to e2e.setRoomKeyID API Rocket.Chat#36716Statistics (0 / 15 completed)
User Management (4 / 52 completed)
permissions.listAllfeat: Add OpenAPI Support to Permissions API Rocket.Chat#35985permissions.updatefeat: Add OpenAPI Support to Permissions API Rocket.Chat#35985Let me know if you'd like these grouped, categorized, or documented further.
📝 Secondary API Endpoints
These 2 endpoints are lower priority and can be migrated after core APIs: (calculating...)
Statistics (0 / 1 completed)
User Management (0 / 1 completed)
Notifications (1 / 1 completed)
push.testchore: Add OpenAPI Support to push.test API Rocket.Chat#36882📌 Important Notes
When migrating endpoints to the new OpenAPI + AJV pattern, keep these points in mind:
No Change in Logic
Error Response Codes
400(Bad Request) → Should be included for most endpoints with input validation.401(Unauthorized) → Add only if the endpointauthRequired: trueis included.403(Forbidden) → Add only if specific permission checks are performed.Schema Validation
$refschemas where available instead of manually defining large object shapes.Centralized Error Validators
validateBadRequestErrorResponseinstead of hard-coding error schemas.Route Definition Style
.post(),.get(), etc.).ExtractRoutesFromAPIautomatically groups routes under the same path in the type definitions.Optional Properties
permissionsRequired, omit it.No More
rest-typingsor Manual Typingsrest-typingsor other manual typing files — everything for an endpoint lives in one place for easier maintenance.Swagger Documentation
📖 Example: Migrating from Old Pattern to New Pattern
This example shows how to migrate from the legacy
addRouteapproach (with manual typings and deprecated validation)to the new typed API definition pattern using:
API.v1.post()/.get()chaining (so multiple HTTP methods for the same path are merged in typings)$reffor shared model schemasExtractRoutesFromAPI(no more manual duplication)Before – Old Pattern
Problems with the old approach:
validateParamsis deprecated → doesn’t integrate with the new pattern.rest-typings→ easy to forget or let them get out of sync.After – New Pattern
Key Improvements in the New Pattern
Single source of truth for typings
ExtractRoutesFromAPIpulls types directly from yourpost()/get()definitions — no more manual edits inrest-typings.Strong request validation with AJV
Both
body(POST) andquery(GET) are validated against JSON schemas.Strong response validation
Ensures the API always returns objects that match the documented shape.
Reusable schemas with Typia
$ref: '#/components/schemas/IBaz'links to a single IBaz schema used across APIs.Predefined error validators
validateBadRequestErrorResponse,validateUnauthorizedErrorResponse,validateForbiddenErrorResponsereplace repetitive error schemas.Chaining multiple methods on the same path
Calling
.post().get()on the samefooEndpointsensures both methods are merged into one entry in the generatedEndpointsinterface.🧪 Testing Plan
💡 Notes