openapi: 3.0.3 info: title: Remindax API description: | ## Getting Started Create an API app in [Settings → Developers](https://app.remindax.com/settings?tab=developers). Copy the `client_id` and `client_secret` — the secret is shown only once. Exchange them for an access token: `POST https://api.remindax.com/v1/oauth/token` Use `grant_type=client_credentials`, then send the token on later requests as `Authorization: Bearer {token}`. Access tokens last **86400 seconds (24 hours)**. There is no refresh token — POST to the same endpoint again when `expires_in` elapses. An active subscription is required. Expired accounts receive HTTP 403 `subscription_inactive`. ## Authentication All requests to the API must be authenticated with an access token: HTTP Authorization header: ```http Authorization: "Bearer {token}" ``` ## Scopes Tokens may include a space-separated scope list. Use `*` for full access. Resource scopes: - `contacts:read` / `contacts:write` - `companies:read` / `companies:write` - `departments:read` / `departments:write` - `doctypes:read` / `doctypes:write` - `items:read` / `items:write` - `folders:read` / `folders:write` - `tags:read` / `tags:write` - `drive:read` / `drive:write` - `tasks:read` / `tasks:write` - `vehicles:read` / `vehicles:write` - `equipment:read` / `equipment:write` - `locations:read` / `locations:write` ## Endpoints All API requests are made to **https://api.remindax.com/** and all requests are served over HTTPS. The current version is **v1**. ## Formats The API only supports JSON at present. In the request header: ```http Content-Type: "application/json" Accept: "application/json" ``` servers: - url: https://api.remindax.com description: Production tags: - name: Auth description: OAuth and token introspection - name: Companies description: Company management - name: Contact Groups description: Contact group management - name: Contacts description: Contact management - name: Departments description: Department management - name: Document Types description: Document type management - name: Drive description: File uploads and item attachments - name: Folders description: Explorer folder tree used to file items - name: Items description: Tracked documents, expirations, renewals, appointments, and events - name: Reminders description: Item reminder schedules, sequences, and recently sent reminders - name: Tags description: Company tags and item tag assignment - name: Tasks description: Task management - name: Vehicles description: Fleet vehicles and linked tracked items - name: Equipment description: Equipment assets and linked tracked items - name: Locations description: Sites and locations and linked tracked items components: securitySchemes: Authorization: type: apiKey in: header name: Authorization description: Send full header value as `Bearer {token}`. paths: /v1/contacts: get: tags: [Contacts] summary: List contacts operationId: listContacts security: - Authorization: [] parameters: - in: query name: limit schema: { type: integer, minimum: 1, maximum: 200, example: 50 } - in: query name: offset schema: { type: integer, minimum: 0, example: 0 } - in: query name: groupid schema: { type: integer, example: 32205 } - in: query name: deptid schema: { type: integer, example: 17775 } - in: query name: q schema: { type: string, example: john } responses: '200': description: Contacts list content: application/json: example: success: true data: - contact_id: 26860 firstname: John lastname: Doe email: john.doe@example.com groupid: 32205 deptid: 17775 country_code: '1' mobile_code: '437' phone_number: '6475551234' iso: US add_date: '2026-03-25 18:24:50' meta: { total: 1, limit: 50, offset: 0 } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Bearer token is required. } '403': description: Forbidden content: application/json: example: { error: insufficient_scope, error_description: Token does not include required scope., required_scope: contacts:read } post: tags: [Contacts] summary: Create contact operationId: createContact security: - Authorization: [] requestBody: required: true content: application/json: schema: type: object required: [first_name, last_name, email] properties: first_name: { type: string } last_name: { type: string } email: { type: string } deptid: { type: integer } groupid: { type: integer } country_code: { type: string } iso: { type: string } mobile_code: { type: string } phone_number: { type: string } example: first_name: MMM last_name: XXX email: bb@remindax2.com deptid: 17775 groupid: 32205 country_code: '1' iso: US mobile_code: '437' phone_number: '4383031' responses: '201': description: Contact created content: application/json: example: success: true msg: Contact created data: contact_id: 26939 firstname: MMM lastname: XXX email: bb@remindax2.com groupid: 32205 deptid: 17775 country_code: '1' mobile_code: '437' phone_number: '4383031' iso: US add_date: '2026-03-25 18:24:50' '400': description: Validation error content: application/json: example: { success: false, msg: country_code and iso are required together } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { error: insufficient_scope, error_description: Token does not include required scope., required_scope: contacts:write } '409': description: Conflict content: application/json: example: { success: false, msg: Contact email already exists } /v1/contacts/{contact_id}: get: tags: [Contacts] summary: Get contact operationId: getContact security: - Authorization: [] parameters: - in: path name: contact_id required: true description: Contact ID from URL path. schema: { type: integer, example: 26860 } responses: '200': description: Contact content: application/json: example: success: true data: contact_id: 26860 firstname: Jane lastname: Doe email: jane.doe@example.com groupid: 32205 deptid: 17775 country_code: '1' mobile_code: '437' phone_number: '6475551234' iso: US add_date: '2026-03-23 01:34:25' '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { error: insufficient_scope, error_description: Token does not include required scope., required_scope: contacts:read } '404': description: Not found content: application/json: example: { success: false, msg: Contact not found } patch: tags: [Contacts] summary: Update contact operationId: updateContact security: - Authorization: [] parameters: - in: path name: contact_id required: true description: Contact ID from URL path. schema: { type: integer, example: 26860 } requestBody: required: true content: application/json: schema: type: object properties: first_name: { type: string } last_name: { type: string } email: { type: string } groupid: { type: integer } countryid: { type: string } mobile_code: { type: string } phone_number: { type: string } example: first_name: Jane last_name: Doe email: jane.doe@example.com groupid: 32205 responses: '200': description: Contact updated content: application/json: example: success: true msg: Contact updated data: contact_id: 26860 firstname: Jane lastname: Doe email: jane.doe@example.com groupid: 32205 deptid: 17775 country_code: '1' mobile_code: '437' phone_number: '6475551234' iso: US add_date: '2026-03-23 01:34:25' '400': description: Validation error content: application/json: example: { success: false, msg: No updatable fields provided } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { error: insufficient_scope, error_description: Token does not include required scope., required_scope: contacts:write } '404': description: Not found content: application/json: example: { success: false, msg: Contact not found } '409': description: Conflict content: application/json: example: { success: false, msg: Contact email already exists } delete: tags: [Contacts] summary: Delete contact operationId: deleteContact security: - Authorization: [] parameters: - in: path name: contact_id required: true description: Contact ID from URL path. schema: { type: integer, example: 26860 } responses: '200': description: Contact deleted content: application/json: example: { success: true, msg: Contact deleted } '400': description: Validation error content: application/json: example: { success: false, msg: Invalid contact id } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { error: insufficient_scope, error_description: Token does not include required scope., required_scope: contacts:write } '404': description: Not found content: application/json: example: { success: false, msg: Contact not found } /v1/contact-groups: get: tags: [Contact Groups] summary: List contact groups operationId: listContactGroups security: - Authorization: [] parameters: - in: query name: deptid schema: { type: integer, example: 17775 } - in: query name: q schema: { type: string, example: sales } responses: '200': description: Contact groups list content: application/json: example: success: true data: - groupid: 32205 group_name: Default Group deptid: 17775 isdefault: 1 add_date: '2026-03-23 00:12:02' contacts_count: 4 - groupid: 32210 group_name: Sales deptid: 17775 isdefault: 0 add_date: '2026-03-25 10:45:00' contacts_count: 12 '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { error: insufficient_scope, error_description: Token does not include required scope., required_scope: contacts:read } post: tags: [Contact Groups] summary: Create contact group operationId: createContactGroup security: - Authorization: [] requestBody: required: true content: application/json: schema: type: object required: [group_name] properties: group_name: { type: string } deptid: { type: integer } isdefault: { type: integer, enum: [0, 1] } example: group_name: Toronto deptid: 17775 isdefault: 1 responses: '201': description: Contact group created content: application/json: example: success: true msg: New group created data: groupid: 32400 group_name: Toronto deptid: 17775 isdefault: 1 add_date: '2026-03-25 15:20:10' '400': description: Validation error content: application/json: example: { success: false, msg: group_name is required } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { error: insufficient_scope, error_description: Token does not include required scope., required_scope: contacts:write } '409': description: Conflict content: application/json: example: { success: false, msg: Group name already exists } /v1/contact-groups/{group_id}: get: tags: [Contact Groups] summary: Get contact group operationId: getContactGroup security: - Authorization: [] parameters: - in: path name: group_id required: true description: Contact group ID from URL path. schema: { type: integer, example: 32400 } responses: '200': description: Contact group content: application/json: example: success: true data: groupid: 32400 group_name: Toronto deptid: 17775 isdefault: 1 add_date: '2026-03-25 15:20:10' '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { error: insufficient_scope, error_description: Token does not include required scope., required_scope: contacts:read } '404': description: Not found content: application/json: example: { success: false, msg: Group not found } patch: tags: [Contact Groups] summary: Update contact group operationId: updateContactGroup security: - Authorization: [] parameters: - in: path name: group_id required: true description: Contact group ID from URL path. schema: { type: integer, example: 32400 } requestBody: required: true content: application/json: schema: type: object properties: group_name: { type: string } deptid: { type: integer } isdefault: { type: integer, enum: [0, 1] } example: group_name: Toronto - Updated deptid: 17775 isdefault: 0 responses: '200': description: Contact group updated content: application/json: example: success: true msg: Group updated data: groupid: 32400 group_name: Toronto - Updated deptid: 17775 isdefault: 0 add_date: '2026-03-25 15:20:10' '400': description: Validation error content: application/json: example: { success: false, msg: No updatable fields provided } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { error: insufficient_scope, error_description: Token does not include required scope., required_scope: contacts:write } '404': description: Not found content: application/json: example: { success: false, msg: Group not found } '409': description: Conflict content: application/json: example: { success: false, msg: Group name already exists } delete: tags: [Contact Groups] summary: Delete contact group operationId: deleteContactGroup security: - Authorization: [] parameters: - in: path name: group_id required: true description: Contact group ID from URL path. schema: { type: integer, example: 32400 } responses: '200': description: Contact group deleted content: application/json: example: { success: true, msg: Group deleted } '400': description: Validation error content: application/json: example: { success: false, msg: Default group cannot be deleted } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { error: insufficient_scope, error_description: Token does not include required scope., required_scope: contacts:write } '404': description: Not found content: application/json: example: { success: false, msg: Group not found } /v1/contact-groups/{group_id}/default: patch: tags: [Contact Groups] summary: Set contact group as default operationId: setDefaultContactGroup security: - Authorization: [] parameters: - in: path name: group_id required: true description: Contact group ID from URL path. schema: { type: integer, example: 32400 } responses: '200': description: Default contact group set content: application/json: example: success: true msg: Default group set data: groupid: 32400 group_name: Toronto - Updated deptid: 17775 isdefault: 1 add_date: '2026-03-25 15:20:10' '400': description: Validation error content: application/json: example: { success: false, msg: Invalid group department } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { error: insufficient_scope, error_description: Token does not include required scope., required_scope: contacts:write } '404': description: Not found content: application/json: example: { success: false, msg: Group not found } /v1/companies: get: tags: [Companies] summary: List companies operationId: listCompanies security: - Authorization: [] responses: '200': description: Companies list content: application/json: example: success: true data: - companyid: 910 name: Remindax Canada isdefault: 1 documents_limit: 1000 documents_used: 42 contacts_limit: 5000 contacts_used: 350 drive_space_mb: 10240 drive_space_gb: 10.24 drive_space_used_kb: 845300 add_date: '2026-03-01 09:00:00' meta: limits: companies: 10 documents: 10000 contacts: 50000 drive_space_mb: 51200 used: companies: 2 documents_allocated: 3000 contacts_allocated: 10000 drive_space_allocated_mb: 15360 '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { error: insufficient_scope, error_description: Token does not include required scope., required_scope: companies:read } post: tags: [Companies] summary: Create company operationId: createCompany security: - Authorization: [] requestBody: required: true content: application/json: schema: type: object required: [company_name, documents_limit, contacts_limit, drive_space] properties: company_name: { type: string } documents_limit: { type: integer } contacts_limit: { type: integer } drive_space: { type: number, description: Drive space in GB } example: company_name: Remindax Europe documents_limit: 1500 contacts_limit: 8000 drive_space: 15 responses: '201': description: Company created content: application/json: example: success: true msg: Company created data: company: companyid: 920 name: Remindax Europe isdefault: 0 documents_limit: 1500 documents_used: 0 contacts_limit: 8000 contacts_used: 0 drive_space_mb: 15000 drive_space_gb: 15 drive_space_used_kb: 0 add_date: '2026-03-25 17:05:00' info: {} settings: {} '400': description: Validation error content: application/json: example: { success: false, msg: company_name, documents_limit, contacts_limit and drive_space are required } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { success: false, msg: Only account owner can manage companies } /v1/companies/{company_id}: get: tags: [Companies] summary: Get company details operationId: showCompany security: - Authorization: [] parameters: - in: path name: company_id required: true description: Company ID from URL path. schema: { type: integer, example: 920 } responses: '200': description: Company details content: application/json: example: success: true data: company: companyid: 920 name: Remindax Europe isdefault: 0 documents_limit: 1500 documents_used: 120 contacts_limit: 8000 contacts_used: 450 drive_space_mb: 15000 drive_space_gb: 15 drive_space_used_kb: 250000 add_date: '2026-03-25 17:05:00' info: business_name: Remindax Europe Ltd city: Toronto id_country: 38 id_industry: 2 id_size: 4 settings: date_format: Y-m-d timezone: America/Toronto '400': description: Validation error content: application/json: example: { success: false, msg: Invalid company id } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { error: insufficient_scope, error_description: Token does not include required scope., required_scope: companies:read } '404': description: Not found content: application/json: example: { success: false, msg: Company not found } patch: tags: [Companies] summary: Update company limits and name operationId: updateCompany security: - Authorization: [] parameters: - in: path name: company_id required: true description: Company ID from URL path. schema: { type: integer, example: 920 } requestBody: required: true content: application/json: schema: type: object required: [company_name, documents_limit, contacts_limit, drive_space] properties: company_name: { type: string } documents_limit: { type: integer } contacts_limit: { type: integer } drive_space: { type: number, description: Drive space in GB } example: company_name: Remindax Europe Updated documents_limit: 2000 contacts_limit: 9000 drive_space: 20 responses: '200': description: Company updated content: application/json: example: success: true msg: Company updated data: company: companyid: 920 name: Remindax Europe Updated isdefault: 0 documents_limit: 2000 documents_used: 120 contacts_limit: 9000 contacts_used: 450 drive_space_mb: 20000 drive_space_gb: 20 drive_space_used_kb: 250000 add_date: '2026-03-25 17:05:00' info: {} settings: {} '400': description: Validation error content: application/json: example: { success: false, msg: Remaining contacts limit is 300 } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { success: false, msg: Only account owner can manage companies } '404': description: Not found content: application/json: example: { success: false, msg: Company not found } delete: tags: [Companies] summary: Delete company operationId: deleteCompany security: - Authorization: [] parameters: - in: path name: company_id required: true description: Company ID from URL path. schema: { type: integer, example: 920 } responses: '200': description: Company deleted content: application/json: example: { success: true, msg: Company deleted } '400': description: Validation or business-rule error content: application/json: example: { success: false, msg: Cannot delete default company } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { success: false, msg: Only account owner can manage companies } '404': description: Not found content: application/json: example: { success: false, msg: Company not found } /v1/companies/{company_id}/info: patch: tags: [Companies] summary: Update company profile info operationId: updateCompanyInfo security: - Authorization: [] parameters: - in: path name: company_id required: true description: Company ID from URL path. schema: { type: integer, example: 920 } requestBody: required: true content: application/json: schema: type: object properties: business_name: { type: string } address1: { type: string } address2: { type: string } city: { type: string } state: { type: string } zipcode: { type: string } id_country: { type: integer } id_industry: { type: integer } id_size: { type: integer } phone: { type: string } email: { type: string } website: { type: string } example: business_name: Remindax Europe Ltd address1: 123 Bay Street city: Toronto state: ON zipcode: M5J2P1 id_country: 38 id_industry: 2 id_size: 4 phone: '+1 437 555 7890' email: info@remindax.eu website: https://remindax.eu responses: '200': description: Company info updated content: application/json: example: success: true msg: Company info saved data: companyid: 920 business_name: Remindax Europe Ltd city: Toronto id_country: 38 id_industry: 2 id_size: 4 '400': description: Validation error content: application/json: example: { success: false, msg: Please select country } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { success: false, msg: Only account owner can manage companies } '404': description: Not found content: application/json: example: { success: false, msg: Company not found } /v1/companies/{company_id}/default: patch: tags: [Companies] summary: Set company as default operationId: setDefaultCompany security: - Authorization: [] parameters: - in: path name: company_id required: true description: Company ID from URL path. schema: { type: integer, example: 920 } responses: '200': description: Default company set content: application/json: example: { success: true, msg: Default company set } '400': description: Validation error content: application/json: example: { success: false, msg: Invalid company id } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { success: false, msg: Only account owner can manage companies } '404': description: Not found content: application/json: example: { success: false, msg: Company not found } /v1/departments: get: tags: [Departments] summary: List departments operationId: listDepartments security: - Authorization: [] parameters: - in: query name: q schema: { type: string, example: general } responses: '200': description: Departments list content: application/json: example: success: true data: - deptid: 17775 name: General isdefault: 1 add_date: '2026-03-23 00:12:02' docs_used: 12 contacts_used: 140 storage_used_kb: 43210 - deptid: 17790 name: Sales isdefault: 0 add_date: '2026-03-26 09:15:00' docs_used: 3 contacts_used: 20 storage_used_kb: 740 '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { success: false, msg: Only account owner can manage departments } post: tags: [Departments] summary: Create department operationId: createDepartment security: - Authorization: [] requestBody: required: true content: application/json: schema: type: object required: [dept_name] properties: dept_name: { type: string } isdefault: { type: integer, enum: [0, 1] } example: dept_name: Compliance isdefault: 0 responses: '201': description: Department created content: application/json: example: success: true msg: Department created data: deptid: 17820 name: Compliance isdefault: 0 add_date: '2026-03-27 10:00:00' docs_used: 0 contacts_used: 0 storage_used_kb: 0 '400': description: Validation error content: application/json: example: { success: false, msg: dept_name is required } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { success: false, msg: Only account owner can manage departments } '409': description: Conflict content: application/json: example: { success: false, msg: Department name already exists } /v1/departments/{dept_id}: get: tags: [Departments] summary: Get department details operationId: getDepartment security: - Authorization: [] parameters: - in: path name: dept_id required: true description: Department ID from URL path. schema: { type: integer, example: 17775 } responses: '200': description: Department details content: application/json: example: success: true data: deptid: 17775 name: General isdefault: 1 add_date: '2026-03-23 00:12:02' docs_used: 12 contacts_used: 140 storage_used_kb: 43210 '400': description: Validation error content: application/json: example: { success: false, msg: Invalid department id } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { success: false, msg: Only account owner can manage departments } '404': description: Not found content: application/json: example: { success: false, msg: Department not found } patch: tags: [Departments] summary: Update department operationId: updateDepartment security: - Authorization: [] parameters: - in: path name: dept_id required: true description: Department ID from URL path. schema: { type: integer, example: 17775 } requestBody: required: true content: application/json: schema: type: object properties: dept_name: { type: string } isdefault: { type: integer, enum: [0, 1] } example: dept_name: Compliance and Risk isdefault: 1 responses: '200': description: Department updated content: application/json: example: success: true msg: Department updated data: deptid: 17775 name: Compliance and Risk isdefault: 1 add_date: '2026-03-23 00:12:02' docs_used: 12 contacts_used: 140 storage_used_kb: 43210 '400': description: Validation error content: application/json: example: { success: false, msg: No updatable fields provided } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { success: false, msg: Only account owner can manage departments } '404': description: Not found content: application/json: example: { success: false, msg: Department not found } '409': description: Conflict content: application/json: example: { success: false, msg: Department name already exists } delete: tags: [Departments] summary: Delete department operationId: deleteDepartment security: - Authorization: [] parameters: - in: path name: dept_id required: true description: Department ID from URL path. schema: { type: integer, example: 17775 } responses: '200': description: Department deleted content: application/json: example: { success: true, msg: Department deleted } '400': description: Validation or business-rule error content: application/json: example: { success: false, msg: Cannot delete department with active records } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { success: false, msg: Only account owner can manage departments } '404': description: Not found content: application/json: example: { success: false, msg: Department not found } /v1/document-types: get: tags: [Document Types] summary: List document types operationId: listDocumentTypes security: - Authorization: [] parameters: - in: query name: deptid schema: { type: integer, example: 17775 } - in: query name: q schema: { type: string, example: passport } responses: '200': description: Document types list content: application/json: example: success: true data: - typeid: 508 name: Passport deptid: 17775 isdefault: 1 add_date: '2026-03-25 14:15:00' docs_count: 24 - typeid: 512 name: Driving License deptid: 17775 isdefault: 0 add_date: '2026-03-25 14:17:00' docs_count: 8 meta: total: 2 max_allowed: 1000 '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { success: false, msg: Only account owner can manage document types } post: tags: [Document Types] summary: Create document type operationId: createDocumentType security: - Authorization: [] requestBody: required: true content: application/json: schema: type: object required: [doctype_name] properties: doctype_name: { type: string } deptid: { type: integer } isdefault: { type: integer, enum: [0, 1] } fields: type: array items: type: object properties: field_name: { type: string } field_type: { type: string } field_data: { type: string } private: { type: integer, enum: [0, 1] } example: doctype_name: Vehicle Insurance deptid: 17775 isdefault: 0 fields: - field_name: Policy Number field_type: text field_data: '' private: 0 - field_name: Expiry Date field_type: date field_data: '' private: 0 responses: '201': description: Document type created content: application/json: example: success: true msg: New document type saved data: typeid: 620 name: Vehicle Insurance deptid: 17775 isdefault: 0 add_date: '2026-03-27 10:20:00' empid: 0 docs_count: 0 fields: - autonum: 1 field_name: Policy Number field_type: text field_data: '' private: 0 - autonum: 2 field_name: Expiry Date field_type: date field_data: '' private: 0 '400': description: Validation error content: application/json: example: { success: false, msg: Document type name is required } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { success: false, msg: Only account owner can manage document types } '409': description: Conflict content: application/json: example: { success: false, msg: Document type already exist } /v1/document-types/{type_id}: get: tags: [Document Types] summary: Get document type details operationId: getDocumentType security: - Authorization: [] parameters: - in: path name: type_id required: true description: Document type ID from URL path. schema: { type: integer, example: 620 } responses: '200': description: Document type details content: application/json: example: success: true data: typeid: 620 name: Vehicle Insurance deptid: 17775 isdefault: 0 add_date: '2026-03-27 10:20:00' empid: 0 docs_count: 0 fields: - autonum: 1 field_name: Policy Number field_type: text field_data: '' private: 0 '400': description: Validation error content: application/json: example: { success: false, msg: Invalid document type id } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { success: false, msg: Only account owner can manage document types } '404': description: Not found content: application/json: example: { success: false, msg: Document type not found } patch: tags: [Document Types] summary: Update document type operationId: updateDocumentType security: - Authorization: [] parameters: - in: path name: type_id required: true description: Document type ID from URL path. schema: { type: integer, example: 620 } requestBody: required: true content: application/json: schema: type: object properties: doctype_name: { type: string } isdefault: { type: integer, enum: [0, 1] } fields: type: array items: type: object properties: field_name: { type: string } field_type: { type: string } field_data: { type: string } private: { type: integer, enum: [0, 1] } example: doctype_name: Vehicle Insurance Updated isdefault: 1 fields: - field_name: Policy Number field_type: text field_data: '' private: 1 - field_name: Expiry Date field_type: date field_data: '' private: 0 responses: '200': description: Document type updated content: application/json: example: success: true msg: Document type updated data: typeid: 620 name: Vehicle Insurance Updated deptid: 17775 isdefault: 1 add_date: '2026-03-27 10:20:00' empid: 0 docs_count: 0 fields: - autonum: 1 field_name: Policy Number field_type: text field_data: '' private: 1 - autonum: 2 field_name: Expiry Date field_type: date field_data: '' private: 0 '400': description: Validation error content: application/json: example: { success: false, msg: No updatable fields provided } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { success: false, msg: Only account owner can manage document types } '404': description: Not found content: application/json: example: { success: false, msg: Document type not found } '409': description: Conflict content: application/json: example: { success: false, msg: Document type already exist } delete: tags: [Document Types] summary: Delete document type operationId: deleteDocumentType security: - Authorization: [] parameters: - in: path name: type_id required: true description: Document type ID from URL path. schema: { type: integer, example: 620 } responses: '200': description: Document type deleted content: application/json: example: { success: true, msg: Document type deleted } '400': description: Validation or business-rule error content: application/json: example: { success: false, msg: Cannot delete. There are 2 documents associated with it } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Token is invalid or expired. } '403': description: Forbidden content: application/json: example: { success: false, msg: Only account owner can manage document types } '404': description: Not found content: application/json: example: { success: false, msg: Document type not found } /v1/oauth/token: post: tags: [Auth] summary: Issue access token (client credentials) operationId: issuePartnerAccessToken security: [] parameters: - in: header name: Authorization required: false description: Bearer {token} schema: type: string example: Bearer cmR4X2NsaWVudF9pZDpyZHhzX2NsaWVudF9zZWNyZXQ= requestBody: required: true content: application/json: schema: type: object required: [grant_type] properties: grant_type: type: string enum: [client_credentials] client_id: type: string client_secret: type: string scope: type: string description: Optional space-separated scope list. example: grant_type: client_credentials client_id: rdx_76b960f652a81d11cec522d2 client_secret: rdxs_1eaf40b7eec1ffe953fa41f2a824f55578596817d05ba8e4 scope: contacts:read contacts:write responses: '200': description: Access token issued. `expires_in` is 86400 seconds (24 hours). content: application/json: example: token_type: Bearer access_token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9... expires_in: 86400 scope: contacts:read contacts:write '400': description: Invalid grant type or scope content: application/json: examples: unsupported_grant_type: value: error: unsupported_grant_type error_description: Only client_credentials grant type is supported. invalid_scope: value: error: invalid_scope error_description: Requested scope is not allowed for this client. '401': description: Invalid client credentials content: application/json: example: error: invalid_client error_description: Client authentication failed. '403': description: Subscription inactive content: application/json: example: error: subscription_inactive error_description: An active subscription is required to use the API. '500': description: Server configuration error content: application/json: example: error: server_error error_description: Token signing key is not configured. '503': description: Credential store unavailable content: application/json: example: error: service_unavailable error_description: API credential store is not ready. /v1/oauth/me: get: tags: [Auth] summary: Inspect current access token operationId: partnerTokenMe security: - Authorization: [] responses: '200': description: Token details content: application/json: example: client_id: rdx_76b960f652a81d11cec522d2 company_id: 910 userid: 1 scope: contacts:read contacts:write exp: 1774694400 iat: 1774608000 '401': description: Invalid or missing token content: application/json: examples: missing_bearer: value: error: invalid_token error_description: Bearer token is required. invalid_or_expired: value: error: invalid_token error_description: Token is invalid or expired. inactive_client: value: error: invalid_token error_description: Client is not active. '403': description: Subscription inactive content: application/json: example: error: subscription_inactive error_description: An active subscription is required to use the API. '500': description: Server configuration error content: application/json: example: error: server_error error_description: Token signing key is not configured. /v1/items: get: tags: [Items] summary: List items operationId: listItems security: - Authorization: [] parameters: - in: query name: limit schema: { type: integer, minimum: 1, maximum: 200, example: 50 } - in: query name: offset schema: { type: integer, minimum: 0, example: 0 } - in: query name: deptid schema: { type: integer } - in: query name: item_type schema: { type: string, enum: [exp, due, apt, evt, all], example: exp } - in: query name: period schema: { type: string, example: '1 Month' } - in: query name: status schema: { type: string, enum: [completed, pending, any] } - in: query name: document_type_id schema: { type: integer } - in: query name: contact_id schema: { type: integer } - in: query name: folder_id schema: { type: integer } - in: query name: q schema: { type: string } responses: '200': description: Items list content: application/json: example: success: true data: - item_id: 41231234 title: Passport item_type: exp document_type: Passport document_type_id: 88 deptid: 17775 expiry_date: '2026-12-01' status: pending folder_id: 0 active: true meta: { total: 1, limit: 50, offset: 0 } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Bearer token is required. } '403': description: Forbidden content: application/json: example: { error: insufficient_scope, error_description: Token does not include required scope., required_scope: items:read } post: tags: [Items] summary: Create item operationId: createItem security: - Authorization: [] requestBody: required: true content: application/json: schema: type: object required: [title, expiry_date] properties: title: { type: string } expiry_date: { type: string, example: '2026-12-01' } item_type: { type: string, enum: [exp, due, apt, evt] } document_type_id: { type: integer } document_type: { type: string } deptid: { type: integer } folder_id: { type: integer } folder_path: { type: string } notes: { type: string } contact_id: { type: integer } seqid: { type: integer } example: title: Passport expiry_date: '2026-12-01' item_type: exp document_type: Passport deptid: 17775 contact_id: 26860 responses: '201': description: Item created content: application/json: example: success: true msg: Item created data: item_id: 41231234 title: Passport expiry_date: '2026-12-01' item_type: exp '400': description: Validation error content: application/json: example: { success: false, msg: title and expiry_date are required } '403': description: Forbidden content: application/json: example: { error: insufficient_scope, error_description: Token does not include required scope., required_scope: items:write } /v1/items/{item_id}: get: tags: [Items] summary: Get item operationId: getItem security: - Authorization: [] parameters: - in: path name: item_id required: true schema: { type: integer, example: 41231234 } responses: '200': description: Item detail content: application/json: example: success: true data: item_id: 41231234 title: Passport item_type: exp expiry_date: '2026-12-01' status: pending tags: [travel] reminders: queued: [] sent: [] '404': description: Not found content: application/json: example: { success: false, msg: Item not found } patch: tags: [Items] summary: Update item operationId: updateItem security: - Authorization: [] parameters: - in: path name: item_id required: true schema: { type: integer } requestBody: required: true content: application/json: schema: type: object properties: title: { type: string } notes: { type: string } folder_id: { type: integer } document_type_id: { type: integer } expiry_date: { type: string } reschedule_reminders: { type: boolean } example: title: Passport (renewed) expiry_date: '2027-12-01' responses: '200': description: Item updated content: application/json: example: { success: true, msg: Item updated } '404': description: Not found content: application/json: example: { success: false, msg: Item not found } delete: tags: [Items] summary: Delete item operationId: deleteItem security: - Authorization: [] parameters: - in: path name: item_id required: true schema: { type: integer } responses: '200': description: Item deleted content: application/json: example: { success: true, msg: Item deleted } '404': description: Not found content: application/json: example: { success: false, msg: Item not found } /v1/items/{item_id}/status: patch: tags: [Items] summary: Set item status operationId: setItemStatus security: - Authorization: [] parameters: - in: path name: item_id required: true schema: { type: integer } requestBody: required: true content: application/json: schema: type: object required: [status] properties: status: { type: string, enum: [completed, pending] } example: { status: completed } responses: '200': description: Status updated content: application/json: example: { success: true, msg: Item status updated } /v1/items/{item_id}/archive: patch: tags: [Items] summary: Archive or restore item operationId: archiveItem security: - Authorization: [] parameters: - in: path name: item_id required: true schema: { type: integer } requestBody: content: application/json: schema: type: object properties: archived: { type: boolean } example: { archived: true } responses: '200': description: Archive state updated content: application/json: example: { success: true, msg: Item archived } /v1/items/{item_id}/renew: post: tags: [Items] summary: Renew item operationId: renewItem security: - Authorization: [] parameters: - in: path name: item_id required: true schema: { type: integer } requestBody: content: application/json: schema: type: object properties: expiry_date: { type: string, example: '2027-12-01' } responses: '200': description: Item renewed content: application/json: example: { success: true, msg: Item renewed } /v1/items/{item_id}/reminders: get: tags: [Reminders] summary: List item reminders operationId: listItemReminders security: - Authorization: [] parameters: - in: path name: item_id required: true schema: { type: integer } responses: '200': description: Reminders content: application/json: example: success: true data: queued: - reminder_id: 91 date: '2026-11-01' hour: '10' sent: false sent: [] post: tags: [Reminders] summary: Create item reminder operationId: createItemReminder security: - Authorization: [] parameters: - in: path name: item_id required: true schema: { type: integer } requestBody: required: true content: application/json: schema: type: object properties: date: { type: string, example: '2026-11-01' } hour: { type: string, example: '10' } period: { type: integer } unit: { type: string, example: Week } rtype: { type: integer, example: 1 } contact_id: { type: integer } channels: { type: array, items: { type: string } } example: date: '2026-11-01' hour: '10' contact_id: 26860 channels: [email] responses: '201': description: Reminder created content: application/json: example: { success: true, msg: Reminder created } /v1/items/{item_id}/reminders/{reminder_id}: patch: tags: [Reminders] summary: Update item reminder operationId: updateItemReminder security: - Authorization: [] parameters: - in: path name: item_id required: true schema: { type: integer } - in: path name: reminder_id required: true schema: { type: integer } requestBody: required: true content: application/json: schema: type: object properties: date: { type: string } hour: { type: string } period: { type: integer } unit: { type: string } rtype: { type: integer } responses: '200': description: Reminder updated content: application/json: example: { success: true, msg: Reminder updated } delete: tags: [Reminders] summary: Delete item reminder operationId: deleteItemReminder security: - Authorization: [] parameters: - in: path name: item_id required: true schema: { type: integer } - in: path name: reminder_id required: true schema: { type: integer } responses: '200': description: Reminder deleted content: application/json: example: { success: true, msg: Reminder deleted } /v1/reminder-sequences: get: tags: [Reminders] summary: List reminder sequences operationId: listReminderSequences security: - Authorization: [] responses: '200': description: Sequences content: application/json: example: success: true data: - seqid: 12 name: Default isdefault: 1 reminders: - period: 1 unit: month type: 1 hour: '10' /v1/reminders/triggered: get: tags: [Reminders] summary: List recently sent reminders operationId: listTriggeredReminders security: - Authorization: [] parameters: - in: query name: limit schema: { type: integer, minimum: 1, maximum: 100, example: 50 } responses: '200': description: Triggered reminders content: application/json: example: success: true data: - reminder_id: 91 item_id: 41231234 title: Passport date: '2026-03-01' hour: '10' /v1/folders: get: tags: [Folders] summary: List folders operationId: listFolders security: - Authorization: [] parameters: - in: query name: deptid schema: { type: integer } - in: query name: parent_id schema: { type: integer } - in: query name: q schema: { type: string } responses: '200': description: Folders content: application/json: example: success: true data: - folderid: 44 parentid: 0 folder_name: Clients deptid: 17775 meta: { total: 1 } post: tags: [Folders] summary: Create folder operationId: createFolder security: - Authorization: [] requestBody: required: true content: application/json: schema: type: object required: [folder_name] properties: folder_name: { type: string } description: { type: string } deptid: { type: integer } parent_id: { type: integer } example: folder_name: Clients deptid: 17775 responses: '201': description: Folder created content: application/json: example: { success: true, msg: Folder created } /v1/folders/{folder_id}: get: tags: [Folders] summary: Get folder operationId: getFolder security: - Authorization: [] parameters: - in: path name: folder_id required: true schema: { type: integer } responses: '200': description: Folder content: application/json: example: { success: true, data: { folderid: 44, folder_name: Clients } } '404': description: Not found content: application/json: example: { success: false, msg: Folder not found } patch: tags: [Folders] summary: Update folder operationId: updateFolder security: - Authorization: [] parameters: - in: path name: folder_id required: true schema: { type: integer } requestBody: required: true content: application/json: schema: type: object properties: folder_name: { type: string } description: { type: string } responses: '200': description: Folder updated content: application/json: example: { success: true, msg: Folder updated } delete: tags: [Folders] summary: Delete folder operationId: deleteFolder security: - Authorization: [] parameters: - in: path name: folder_id required: true schema: { type: integer } responses: '200': description: Folder deleted content: application/json: example: { success: true, msg: Folder deleted } '409': description: Conflict content: application/json: example: { success: false, msg: Folder is not empty } /v1/tags: get: tags: [Tags] summary: List tags operationId: listTags security: - Authorization: [] parameters: - in: query name: q schema: { type: string } responses: '200': description: Tags content: application/json: example: success: true data: - tag_id: 9 name: travel items_count: 3 /v1/items/{item_id}/tags: put: tags: [Tags] summary: Replace item tags operationId: replaceItemTags security: - Authorization: [] parameters: - in: path name: item_id required: true schema: { type: integer } requestBody: required: true content: application/json: schema: type: object required: [tags] properties: tags: { type: array, items: { type: string } } example: { tags: [travel, passport] } responses: '200': description: Tags updated content: application/json: example: { success: true, msg: Tags updated, data: [travel, passport] } /v1/uploads: post: tags: [Drive] summary: Create upload session operationId: createUpload security: - Authorization: [] requestBody: required: true content: application/json: schema: type: object required: [filename] properties: filename: { type: string, example: passport.pdf } content_type: { type: string, example: application/pdf } deptid: { type: integer } folder_id: { type: integer } responses: '201': description: Upload session content: application/json: example: success: true data: upload_url: https://api.remindax.com/v1/uploads upload_token: eyJ... method: PUT token_header: X-Upload-Token expires_in: 900 put: tags: [Drive] summary: Upload file bytes operationId: receiveUpload security: [] parameters: - in: header name: X-Upload-Token required: true schema: { type: string } requestBody: required: true content: application/octet-stream: schema: { type: string, format: binary } responses: '200': description: File stored content: application/json: example: success: true data: file_id: ab12cd34ef56 file_name: passport.pdf /v1/items/{item_id}/attachments: get: tags: [Drive] summary: List item attachments operationId: listItemAttachments security: - Authorization: [] parameters: - in: path name: item_id required: true schema: { type: integer } responses: '200': description: Attachments content: application/json: example: success: true data: - file_id: ab12cd34ef56 file_name: passport.pdf size: '120 KB' post: tags: [Drive] summary: Attach file to item operationId: attachFileToItem security: - Authorization: [] parameters: - in: path name: item_id required: true schema: { type: integer } requestBody: required: true content: application/json: schema: type: object required: [file_id] properties: file_id: { type: string } example: { file_id: ab12cd34ef56 } responses: '201': description: Attachment added content: application/json: example: { success: true, msg: Attachment added } /v1/tasks: get: tags: [Tasks] summary: List tasks operationId: listTasks security: - Authorization: [] parameters: - in: query name: limit schema: { type: integer, example: 50 } - in: query name: offset schema: { type: integer, example: 0 } - in: query name: status schema: { type: string, enum: [open, todo, in_progress, review, completed, canceled] } - in: query name: assignee_id schema: { type: integer } - in: query name: q schema: { type: string } responses: '200': description: Tasks content: application/json: example: success: true data: - task_id: 12 public_id: a1b2c3 title: Call client status: open priority: normal due_at: '2026-09-10 09:00:00' meta: { total: 1, limit: 50, offset: 0 } post: tags: [Tasks] summary: Create task operationId: createTask security: - Authorization: [] requestBody: required: true content: application/json: schema: type: object required: [title, due_at] properties: title: { type: string } description: { type: string } due_at: { type: string, example: '2026-09-10 09:00:00' } status: { type: string } priority: { type: string } ownerid: { type: integer } assignee_type: { type: string } assignee_id: { type: integer } example: title: Call client due_at: '2026-09-10 09:00:00' priority: high responses: '201': description: Task created content: application/json: example: { success: true, msg: Task created } /v1/tasks/{task_id}: get: tags: [Tasks] summary: Get task operationId: getTask security: - Authorization: [] parameters: - in: path name: task_id required: true schema: { type: string } responses: '200': description: Task content: application/json: example: { success: true, data: { task_id: 12, title: Call client, status: open } } '404': description: Not found content: application/json: example: { success: false, msg: Task not found } patch: tags: [Tasks] summary: Update task operationId: updateTask security: - Authorization: [] parameters: - in: path name: task_id required: true schema: { type: string } requestBody: required: true content: application/json: schema: type: object properties: title: { type: string } description: { type: string } due_at: { type: string } status: { type: string } priority: { type: string } ownerid: { type: integer } assignee_type: { type: string } assignee_id: { type: integer } responses: '200': description: Task updated content: application/json: example: { success: true, msg: Task updated } delete: tags: [Tasks] summary: Delete task operationId: deleteTask security: - Authorization: [] parameters: - in: path name: task_id required: true schema: { type: string } responses: '200': description: Task deleted content: application/json: example: { success: true, msg: Task deleted } /v1/vehicles: get: tags: [Vehicles] summary: List vehicles operationId: listVehicles security: - Authorization: [] parameters: - in: query name: limit schema: { type: integer, minimum: 1, maximum: 200, example: 50 } - in: query name: offset schema: { type: integer, minimum: 0, example: 0 } - in: query name: deptid schema: { type: integer } - in: query name: q schema: { type: string, example: ABC-123 } - in: query name: status schema: { type: string, enum: [active, maintenance, retired] } - in: query name: compliance_status schema: { type: string, enum: [compliant, expiring_soon, expired, no_documents] } - in: query name: vehicle_type schema: { type: string, enum: [car, truck, van, heavy_equipment, motorcycle, trailer, other] } responses: '200': description: Vehicles content: application/json: example: success: true data: - vehicle_id: 41 license_plate: ABC-123 make: Toyota model: Camry year: 2022 vehicle_type: car status: active compliance_status: no_documents deptid: 17775 reminder_count: 2 meta: { total: 1, limit: 50, offset: 0 } '401': description: Unauthorized content: application/json: example: { error: invalid_token, error_description: Bearer token is required. } '403': description: Forbidden content: application/json: example: { error: insufficient_scope, error_description: Token does not include required scope., required_scope: vehicles:read } post: tags: [Vehicles] summary: Create vehicle operationId: createVehicle security: - Authorization: [] requestBody: required: true content: application/json: schema: type: object required: [license_plate, make, model] properties: license_plate: { type: string } make: { type: string } model: { type: string } vin: { type: string } year: { type: integer, example: 2022 } color: { type: string } vehicle_type: { type: string, enum: [car, truck, van, heavy_equipment, motorcycle, trailer, other] } fuel_type: { type: string, enum: [gasoline, diesel, electric, hybrid, lpg, cng, other] } status: { type: string, enum: [active, maintenance, retired] } deptid: { type: integer } location_id: { type: integer } assigned_driver_contact_id: { type: integer } current_odometer: { type: integer } purchase_date: { type: string, example: '2024-01-15' } insurance_provider: { type: string } notes: { type: string } custom_fields: type: array items: type: object properties: name: { type: string } type: { type: string, enum: [text, date] } value: { type: string } example: license_plate: ABC-123 make: Toyota model: Camry year: 2022 vehicle_type: car deptid: 17775 responses: '201': description: Vehicle created content: application/json: example: { success: true, msg: Vehicle created, data: { vehicle_id: 41, license_plate: ABC-123 } } '400': description: Validation error content: application/json: example: { success: false, msg: 'license_plate, make, and model are required' } '409': description: Duplicate plate content: application/json: example: { success: false, msg: license_plate already exists } /v1/vehicles/{vehicle_id}: get: tags: [Vehicles] summary: Get vehicle operationId: getVehicle security: - Authorization: [] parameters: - in: path name: vehicle_id required: true schema: { type: integer } responses: '200': description: Vehicle content: application/json: example: success: true data: vehicle_id: 41 license_plate: ABC-123 make: Toyota model: Camry items: [] custom_fields: [] '404': description: Not found content: application/json: example: { success: false, msg: Vehicle not found } patch: tags: [Vehicles] summary: Update vehicle operationId: updateVehicle security: - Authorization: [] parameters: - in: path name: vehicle_id required: true schema: { type: integer } requestBody: required: true content: application/json: schema: type: object properties: license_plate: { type: string } make: { type: string } model: { type: string } status: { type: string } current_odometer: { type: integer } location_id: { type: integer } example: { status: maintenance, current_odometer: 18500 } responses: '200': description: Vehicle updated content: application/json: example: { success: true, msg: Vehicle updated } delete: tags: [Vehicles] summary: Delete vehicle operationId: deleteVehicle security: - Authorization: [] parameters: - in: path name: vehicle_id required: true schema: { type: integer } responses: '200': description: Vehicle deleted content: application/json: example: { success: true, msg: Vehicle deleted } /v1/vehicles/{vehicle_id}/items: get: tags: [Vehicles] summary: List items linked to a vehicle operationId: listVehicleItems security: - Authorization: [] parameters: - in: path name: vehicle_id required: true schema: { type: integer } responses: '200': description: Linked items content: application/json: example: success: true data: - item_id: 1201 title: Insurance item_type: exp expiry_date: '2026-12-01' expiry_status: compliant meta: { total: 1 } post: tags: [Vehicles] summary: Link tracked items to a vehicle operationId: linkVehicleItems security: - Authorization: [] parameters: - in: path name: vehicle_id required: true schema: { type: integer } requestBody: required: true content: application/json: schema: type: object properties: item_ids: type: array items: { type: integer } item_id: { type: integer } example: { item_ids: [1201, 1202] } responses: '200': description: Items linked content: application/json: example: { success: true, msg: Items linked, data: { linked: [1201, 1202] } } /v1/vehicles/{vehicle_id}/items/search: get: tags: [Vehicles] summary: Search unlinked items that can be attached to a vehicle operationId: searchVehicleItems security: - Authorization: [] parameters: - in: path name: vehicle_id required: true schema: { type: integer } - in: query name: q schema: { type: string } - in: query name: limit schema: { type: integer, example: 20 } responses: '200': description: Unlinked items content: application/json: example: success: true data: - item_id: 1304 title: Registration item_type: exp expiry_date: '2027-03-01' expiry_status: compliant /v1/vehicles/{vehicle_id}/items/{item_id}: delete: tags: [Vehicles] summary: Unlink an item from a vehicle operationId: unlinkVehicleItem security: - Authorization: [] parameters: - in: path name: vehicle_id required: true schema: { type: integer } - in: path name: item_id required: true schema: { type: integer } responses: '200': description: Item unlinked content: application/json: example: { success: true, msg: Item unlinked } /v1/equipment: get: tags: [Equipment] summary: List equipment operationId: listEquipment security: - Authorization: [] parameters: - in: query name: limit schema: { type: integer, example: 50 } - in: query name: offset schema: { type: integer, example: 0 } - in: query name: deptid schema: { type: integer } - in: query name: q schema: { type: string } - in: query name: status schema: { type: string, enum: [active, maintenance, retired] } - in: query name: compliance_status schema: { type: string, enum: [compliant, expiring_soon, expired, no_documents] } - in: query name: category schema: { type: string, enum: [machinery, tools, it, medical, hvac, electrical, safety, other] } responses: '200': description: Equipment content: application/json: example: success: true data: - equipment_id: 8 name: Compressor serial_number: SN-1 category: tools status: active compliance_status: no_documents meta: { total: 1, limit: 50, offset: 0 } '403': description: Forbidden content: application/json: example: { error: insufficient_scope, error_description: Token does not include required scope., required_scope: equipment:read } post: tags: [Equipment] summary: Create equipment operationId: createEquipment security: - Authorization: [] requestBody: required: true content: application/json: schema: type: object required: [name] properties: name: { type: string } serial_number: { type: string } brand: { type: string } model: { type: string } category: { type: string, enum: [machinery, tools, it, medical, hvac, electrical, safety, other] } vendor: { type: string } status: { type: string, enum: [active, maintenance, retired] } deptid: { type: integer } location_id: { type: integer } assigned_contact_id: { type: integer } purchase_date: { type: string } notes: { type: string } example: name: Compressor serial_number: SN-1 category: tools deptid: 17775 responses: '201': description: Equipment created content: application/json: example: { success: true, msg: Equipment created, data: { equipment_id: 8, name: Compressor } } '409': description: Duplicate serial content: application/json: example: { success: false, msg: serial_number already exists } /v1/equipment/{equipment_id}: get: tags: [Equipment] summary: Get equipment operationId: getEquipment security: - Authorization: [] parameters: - in: path name: equipment_id required: true schema: { type: integer } responses: '200': description: Equipment content: application/json: example: { success: true, data: { equipment_id: 8, name: Compressor, items: [] } } '404': description: Not found content: application/json: example: { success: false, msg: Equipment not found } patch: tags: [Equipment] summary: Update equipment operationId: updateEquipment security: - Authorization: [] parameters: - in: path name: equipment_id required: true schema: { type: integer } requestBody: required: true content: application/json: schema: type: object properties: name: { type: string } serial_number: { type: string } status: { type: string } location_id: { type: integer } example: { status: maintenance } responses: '200': description: Equipment updated content: application/json: example: { success: true, msg: Equipment updated } delete: tags: [Equipment] summary: Delete equipment operationId: deleteEquipment security: - Authorization: [] parameters: - in: path name: equipment_id required: true schema: { type: integer } responses: '200': description: Equipment deleted content: application/json: example: { success: true, msg: Equipment deleted } /v1/equipment/{equipment_id}/items: get: tags: [Equipment] summary: List items linked to equipment operationId: listEquipmentItems security: - Authorization: [] parameters: - in: path name: equipment_id required: true schema: { type: integer } responses: '200': description: Linked items content: application/json: example: { success: true, data: [], meta: { total: 0 } } post: tags: [Equipment] summary: Link tracked items to equipment operationId: linkEquipmentItems security: - Authorization: [] parameters: - in: path name: equipment_id required: true schema: { type: integer } requestBody: required: true content: application/json: schema: type: object properties: item_ids: type: array items: { type: integer } example: { item_ids: [1201] } responses: '200': description: Items linked content: application/json: example: { success: true, msg: Items linked } /v1/equipment/{equipment_id}/items/search: get: tags: [Equipment] summary: Search unlinked items that can be attached to equipment operationId: searchEquipmentItems security: - Authorization: [] parameters: - in: path name: equipment_id required: true schema: { type: integer } - in: query name: q schema: { type: string } responses: '200': description: Unlinked items content: application/json: example: { success: true, data: [] } /v1/equipment/{equipment_id}/items/{item_id}: delete: tags: [Equipment] summary: Unlink an item from equipment operationId: unlinkEquipmentItem security: - Authorization: [] parameters: - in: path name: equipment_id required: true schema: { type: integer } - in: path name: item_id required: true schema: { type: integer } responses: '200': description: Item unlinked content: application/json: example: { success: true, msg: Item unlinked } /v1/locations: get: tags: [Locations] summary: List locations operationId: listLocations security: - Authorization: [] parameters: - in: query name: limit schema: { type: integer, example: 50 } - in: query name: offset schema: { type: integer, example: 0 } - in: query name: deptid schema: { type: integer } - in: query name: q schema: { type: string } - in: query name: status schema: { type: string, enum: [active, inactive] } - in: query name: compliance_status schema: { type: string, enum: [compliant, expiring_soon, expired, no_documents] } responses: '200': description: Locations content: application/json: example: success: true data: - location_id: 3 name: Warehouse A city: Toronto region: ON status: active compliance_status: no_documents meta: { total: 1, limit: 50, offset: 0 } '403': description: Forbidden content: application/json: example: { error: insufficient_scope, error_description: Token does not include required scope., required_scope: locations:read } post: tags: [Locations] summary: Create location operationId: createLocation security: - Authorization: [] requestBody: required: true content: application/json: schema: type: object required: [name] properties: name: { type: string } address: { type: string } city: { type: string } region: { type: string } postal_code: { type: string } country: { type: string } status: { type: string, enum: [active, inactive] } deptid: { type: integer } site_manager_contact_id: { type: integer } notes: { type: string } example: name: Warehouse A city: Toronto region: ON country: CA deptid: 17775 responses: '201': description: Location created content: application/json: example: { success: true, msg: Location created, data: { location_id: 3, name: Warehouse A } } '409': description: Duplicate name content: application/json: example: { success: false, msg: name already exists } /v1/locations/{location_id}: get: tags: [Locations] summary: Get location operationId: getLocation security: - Authorization: [] parameters: - in: path name: location_id required: true schema: { type: integer } responses: '200': description: Location content: application/json: example: { success: true, data: { location_id: 3, name: Warehouse A, items: [] } } '404': description: Not found content: application/json: example: { success: false, msg: Location not found } patch: tags: [Locations] summary: Update location operationId: updateLocation security: - Authorization: [] parameters: - in: path name: location_id required: true schema: { type: integer } requestBody: required: true content: application/json: schema: type: object properties: name: { type: string } city: { type: string } status: { type: string } example: { status: inactive } responses: '200': description: Location updated content: application/json: example: { success: true, msg: Location updated } delete: tags: [Locations] summary: Delete location operationId: deleteLocation security: - Authorization: [] parameters: - in: path name: location_id required: true schema: { type: integer } responses: '200': description: Location deleted content: application/json: example: { success: true, msg: Location deleted } /v1/locations/{location_id}/items: get: tags: [Locations] summary: List items linked to a location operationId: listLocationItems security: - Authorization: [] parameters: - in: path name: location_id required: true schema: { type: integer } responses: '200': description: Linked items content: application/json: example: { success: true, data: [], meta: { total: 0 } } post: tags: [Locations] summary: Link tracked items to a location operationId: linkLocationItems security: - Authorization: [] parameters: - in: path name: location_id required: true schema: { type: integer } requestBody: required: true content: application/json: schema: type: object properties: item_ids: type: array items: { type: integer } example: { item_ids: [1201] } responses: '200': description: Items linked content: application/json: example: { success: true, msg: Items linked } /v1/locations/{location_id}/items/search: get: tags: [Locations] summary: Search unlinked items that can be attached to a location operationId: searchLocationItems security: - Authorization: [] parameters: - in: path name: location_id required: true schema: { type: integer } - in: query name: q schema: { type: string } responses: '200': description: Unlinked items content: application/json: example: { success: true, data: [] } /v1/locations/{location_id}/items/{item_id}: delete: tags: [Locations] summary: Unlink an item from a location operationId: unlinkLocationItem security: - Authorization: [] parameters: - in: path name: location_id required: true schema: { type: integer } - in: path name: item_id required: true schema: { type: integer } responses: '200': description: Item unlinked content: application/json: example: { success: true, msg: Item unlinked }