openapi: 3.0.3 info: title: Duvo Public Agent Folders Credentials API description: Public API for programmatic access to Duvo. Authenticate with API keys created in the Duvo dashboard. version: 1.0.0 servers: - url: https://api.duvo.ai description: Production server tags: - name: Credentials description: Manage logins (domain + username + password + TOTP) used by agents to sign in to websites and desktop applications, and attach them to assignment revisions paths: /v2/agents/{agentId}/revisions/{buildId}/logins: get: operationId: listRevisionLogins tags: - Credentials description: List logins attached to a specific revision (build) of an assignment. Returns metadata only — passwords and OTP secrets are never exposed. parameters: - schema: type: string format: uuid in: path name: agentId required: true - schema: type: string format: uuid in: path name: buildId required: true security: - bearerAuth: [] responses: '200': description: Default Response content: application/json: schema: type: array items: type: object properties: id: type: string format: uuid user_id: nullable: true type: string format: uuid team_id: nullable: true type: string format: uuid domain: type: string username: nullable: true type: string created_at: type: string format: date-time updated_at: type: string format: date-time required: - id - user_id - team_id - domain - username - created_at - updated_at additionalProperties: false '401': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '500': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false summary: List Revision Logins post: operationId: attachRevisionLogin tags: - Credentials description: Attach a login to a revision so the agent can use it during Runs spawned from that revision. Personal logins can only be attached by their owner; team-shared logins require builder permissions. requestBody: required: true content: application/json: schema: type: object properties: exposedCredentialId: type: string format: uuid required: - exposedCredentialId parameters: - schema: type: string format: uuid in: path name: agentId required: true - schema: type: string format: uuid in: path name: buildId required: true security: - bearerAuth: [] responses: '201': description: Default Response content: application/json: schema: type: object properties: success: type: boolean required: - success additionalProperties: false '401': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '403': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '404': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '409': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '500': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false summary: Attach Revision Login /v2/agents/{agentId}/revisions/{buildId}/logins/{exposedCredentialId}: delete: operationId: detachRevisionLogin tags: - Credentials description: Detach a login from a revision. Personal logins can only be detached by their owner; team-shared logins require builder permissions. parameters: - schema: type: string format: uuid in: path name: agentId required: true - schema: type: string format: uuid in: path name: buildId required: true - schema: type: string format: uuid in: path name: exposedCredentialId required: true security: - bearerAuth: [] responses: '200': description: Default Response content: application/json: schema: type: object properties: success: type: boolean required: - success additionalProperties: false '401': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '403': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '404': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '409': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '500': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false summary: Detach Revision Login /v2/teams/{teamId}/browser-agent/credentials/{userId}: get: operationId: listCredentials summary: List credentials for user and team tags: - Credentials description: List browser-login credentials visible to the caller for the current team — team-shared (user_id IS NULL) plus the caller's own personal logins. Optionally filter by `domain`. Passwords and OTP secrets are never returned; only metadata flags indicating whether they are set. parameters: - schema: type: string minLength: 1 in: query name: domain required: false - schema: type: string format: uuid in: path name: userId required: true - schema: type: string format: uuid in: path name: teamId required: true security: - bearerAuth: [] responses: '200': description: Default Response content: application/json: schema: type: array items: type: object properties: id: type: string format: uuid description: Credential ID domain: type: string description: Domain for the credential username: nullable: true description: Username (if any) type: string hasEnabledTOTP: type: boolean description: Whether TOTP is enabled hasPassword: type: boolean description: Whether a password is stored user_id: nullable: true description: Owner user id; null when shared with the team type: string required: - id - domain - username - hasEnabledTOTP - hasPassword - user_id additionalProperties: false '400': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '401': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '403': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '404': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '500': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false post: operationId: createCredential summary: Create credential tags: - Credentials description: 'Create a login. At least one of `password` or `otp_secret` must be provided. Personal by default; pass `shared: true` to create a team-shared login (requires manager role).' requestBody: required: true content: application/json: schema: type: object properties: domain: type: string minLength: 1 username: nullable: true type: string minLength: 1 password: nullable: true type: string minLength: 1 otp_secret: nullable: true type: string minLength: 1 shared: type: boolean required: - domain parameters: - schema: type: string format: uuid in: path name: userId required: true - schema: type: string format: uuid in: path name: teamId required: true security: - bearerAuth: [] responses: '201': description: Default Response content: application/json: schema: type: object properties: id: type: string format: uuid domain: type: string username: nullable: true type: string password: nullable: true otp_secret: nullable: true user_id: nullable: true type: string team_id: type: string created_at: type: string format: date-time updated_at: type: string format: date-time required: - id - domain - username - password - otp_secret - user_id - team_id - created_at - updated_at additionalProperties: false '400': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '401': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '403': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '500': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false /v2/teams/{teamId}/browser-agent/credentials/{userId}/{id}: get: operationId: getCredential summary: Get credential by id tags: - Credentials description: Get a login by id. Returns the encrypted password/otp_secret blobs — only the owner or team members can access it. parameters: - schema: type: string format: uuid in: path name: userId required: true - schema: type: string format: uuid in: path name: teamId required: true - schema: type: string format: uuid in: path name: id required: true security: - bearerAuth: [] responses: '200': description: Default Response content: application/json: schema: type: object properties: id: type: string format: uuid domain: type: string username: nullable: true type: string password: nullable: true otp_secret: nullable: true user_id: nullable: true type: string team_id: type: string created_at: type: string format: date-time updated_at: type: string format: date-time required: - id - domain - username - password - otp_secret - user_id - team_id - created_at - updated_at additionalProperties: false '401': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '403': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '404': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '500': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false patch: operationId: updateCredential summary: Update credential by id tags: - Credentials description: Update a login by id. At least one of password or otp_secret must remain set after the update. Editing a team-shared login or toggling sharing requires manager role. requestBody: required: true content: application/json: schema: type: object properties: domain: type: string minLength: 1 username: nullable: true type: string minLength: 1 password: nullable: true type: string minLength: 1 otp_secret: nullable: true type: string minLength: 1 shared: type: boolean parameters: - schema: type: string format: uuid in: path name: userId required: true - schema: type: string format: uuid in: path name: teamId required: true - schema: type: string format: uuid in: path name: id required: true security: - bearerAuth: [] responses: '200': description: Default Response content: application/json: schema: type: object properties: id: type: string format: uuid domain: type: string username: nullable: true type: string password: nullable: true otp_secret: nullable: true user_id: nullable: true type: string team_id: type: string created_at: type: string format: date-time updated_at: type: string format: date-time required: - id - domain - username - password - otp_secret - user_id - team_id - created_at - updated_at additionalProperties: false '400': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '401': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '403': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '404': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '500': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false delete: operationId: deleteCredential summary: Delete credential by id tags: - Credentials description: Delete a login by id. Deleting a team-shared login requires manager role. parameters: - schema: type: string format: uuid in: path name: userId required: true - schema: type: string format: uuid in: path name: teamId required: true - schema: type: string format: uuid in: path name: id required: true security: - bearerAuth: [] responses: '204': description: Default Response content: application/json: schema: type: string nullable: true enum: - null '401': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '403': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '404': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false '500': description: Default Response content: application/json: schema: type: object properties: error: type: string message: type: string required: - error additionalProperties: false components: securitySchemes: bearerAuth: type: http scheme: bearer description: API key authentication. Get your API key from the Duvo dashboard.