# Detective V3 API Walkthrough
This document provides a comprehensive guide to the Detective V3 API endpoints, including when to use them, required parameters, authorization requirements, and which test accounts to use.
---
## Test Accounts Reference
| Email | Role | 2FA | Brands | Use Case |
|:------|:-----|:----|:-------|:---------|
| `system-administrator@ext.iptwins.com` | System Administrator | TOTP Required | All Brands | Full system access |
| `account-manager@ext.iptwins.com` | Account Manager | None | acme-corp, techstart-inc | Cross-brand management |
| `client-account@ext.iptwins.com` | Client Account | None | acme-corp | Single brand client |
| `external-partner@ext.iptwins.com` | External Partner | None | techstart-inc | External partner access |
| `admin-no2fa@ext.iptwins.com` | System Administrator | None | All Brands | Admin testing without 2FA |
| `admin-needs-setup@ext.iptwins.com` | System Administrator | Setup Required | All Brands | 2FA setup flow testing |
> All test accounts use password: `123456`
---
## IAM Endpoints
### POST /auth/refresh
**Purpose**: Refreshes an expired access token using a refresh token. Essential for M2M (Machine-to-Machine) clients to maintain authenticated sessions without re-authentication.
**When to Use**:
- When the access token expires (default: 1 hour)
- M2M integrations that need long-running authenticated sessions
- Mobile/SPA applications that need to silently refresh tokens
**Authorization**: None (refresh token provides authentication)
**Request Body**:
```json
{
"refreshToken": "eyJfQXV0aEVtdWxhdG9yUmVmcmVzaFRva2VuIjoiRE8gTk9UIE1PRElGWSIs..."
}
```
**Response**:
```json
{
"accessToken": "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0...",
"refreshToken": "eyJfQXV0aEVtdWxhdG9yUmVmcmVzaFRva2VuIjoiRE8gTk9UIE1PRElGWSIs...",
"expiresIn": 3600
}
```
**M2M Token Flow**:
1. Initial login via `/auth/login` returns access + refresh tokens
2. Store refresh token securely
3. When access token expires, call `/auth/refresh` with stored refresh token
4. Replace stored tokens with new ones from response
5. Repeat step 3-4 as needed
**Test Account**: Any account (e.g., `external-partner@ext.iptwins.com`)
---
### GET /users/me
**Purpose**: Retrieves the currently authenticated user's profile information.
**When to Use**:
- After login to display user profile
- To verify current user's role and permissions
- To check which brands the user has access to
**Authorization**: Any authenticated user
**Request Headers**:
```
Authorization: Bearer {accessToken}
```
**Response**:
```json
{
"id": "76554c74-a127-5cdb-a39c-74e49d15c4c0",
"email": "external-partner@ext.iptwins.com",
"displayName": "external-partner",
"roleId": "520f4369-9e75-5613-9ece-eb3248b6b962",
"brandIds": ["beae4937-bf6e-55a8-864b-f56cd63bae95"],
"status": "Active"
}
```
**Test Account**: Any authenticated account
---
### GET /users
**Purpose**: Lists all users in the system with pagination support.
**When to Use**:
- Admin dashboard to manage users
- User search and filtering
- Audit and compliance reporting
**Authorization**: `system-administrator` role only
**Request Headers**:
```
Authorization: Bearer {accessToken}
```
**Query Parameters**:
| Parameter | Type | Default | Description |
|:----------|:-----|:--------|:------------|
| `page` | number | 1 | Page number |
| `limit` | number | 20 | Items per page |
**Response**:
```json
{
"items": [...],
"total": 6,
"page": 1,
"limit": 20
}
```
**Test Account**: `system-administrator@ext.iptwins.com` or `admin-no2fa@ext.iptwins.com`
---
### GET /users/:id
**Purpose**: Retrieves a specific user by their UUID.
**When to Use**:
- View detailed user profile
- Admin user inspection
- Pre-populating user edit forms
**Authorization**: `system-administrator` role only
**Request Headers**:
```
Authorization: Bearer {accessToken}
```
**Path Parameters**:
| Parameter | Type | Description |
|:----------|:-----|:------------|
| `id` | UUID | User's unique identifier |
**Response**:
```json
{
"id": "76554c74-a127-5cdb-a39c-74e49d15c4c0",
"email": "external-partner@ext.iptwins.com",
"displayName": "external-partner",
"roleId": "520f4369-9e75-5613-9ece-eb3248b6b962",
"brandIds": ["beae4937-bf6e-55a8-864b-f56cd63bae95"],
"status": "Active",
"hasAllBrandsAccess": false,
"require2FA": false
}
```
**Test Account**: `system-administrator@ext.iptwins.com` or `admin-no2fa@ext.iptwins.com`
---
### POST /users/sync
**Purpose**: Triggers synchronization of user accounts from Domainarium external system.
**When to Use**:
- Initial system setup
- Periodic user synchronization
- After user changes in Domainarium
**Authorization**: `system-administrator` role only
**Request Headers**:
```
Authorization: Bearer {accessToken}
```
**Response**:
```json
{
"synced": 6,
"created": 0,
"updated": 6
}
```
**Test Account**: `system-administrator@ext.iptwins.com` or `admin-no2fa@ext.iptwins.com`
---
### PATCH /users/batch
**Purpose**: Bulk updates multiple users' status and/or role assignment.
**When to Use**:
- Mass user activation/deactivation
- Batch role reassignment
- User cleanup operations
**Authorization**: `system-administrator` role only
**Request Headers**:
```
Authorization: Bearer {accessToken}
Content-Type: application/json
```
**Request Body**:
```json
{
"userIds": ["uuid1", "uuid2", "uuid3"],
"status": "Active",
"roleId": "520f4369-9e75-5613-9ece-eb3248b6b962"
}
```
| Field | Type | Required | Description |
|:------|:-----|:---------|:------------|
| `userIds` | UUID[] | Yes | Array of user IDs to update |
| `status` | string | No* | New status: `Active`, `Inactive` |
| `roleId` | UUID | No* | New role ID to assign |
> *At least one of `status` or `roleId` must be provided.
**Response**:
```json
{
"success": true,
"updated": 3,
"failed": []
}
```
**Test Account**: `system-administrator@ext.iptwins.com` or `admin-no2fa@ext.iptwins.com`
---
### GET /roles
**Purpose**: Lists all available roles in the system.
**When to Use**:
- Populating role dropdowns in UI
- Understanding role hierarchy
- Role assignment forms
**Authorization**: None (public endpoint)
**Response**:
```json
[
{
"id": "0559e250-9e20-5069-aad6-d42ba3eb8c28",
"name": "System Administrator",
"slug": "system-administrator",
"permissions": ["*"]
},
{
"id": "3893e3e3-c1bf-5313-b718-c04c2fa8b3ef",
"name": "Account Manager",
"slug": "account-manager",
"permissions": ["finding:read", "finding:write", "task:read", "task:write"]
}
]
```
**Test Account**: Any (no authentication required)
---
### GET /permissions
**Purpose**: Lists all available permissions in the system.
**When to Use**:
- Understanding available permissions
- Custom role creation (future)
- Permission documentation
**Authorization**: None (public endpoint)
**Response**:
```json
[
"finding:read",
"finding:write",
"task:read",
"task:write",
"user:read",
"user:write"
]
```
**Test Account**: Any (no authentication required)
---
## Audit Endpoints
### GET /audit-logs
**Purpose**: Queries system-wide audit logs with filtering and pagination.
**When to Use**:
- Compliance auditing
- Security incident investigation
- Activity monitoring
- Debugging and troubleshooting
**Authorization**: `system-administrator` role only
**Request Headers**:
```
Authorization: Bearer {accessToken}
```
**Query Parameters**:
| Parameter | Type | Default | Description |
|:----------|:-----|:--------|:------------|
| `user` | UUID | - | Filter by user ID |
| `scope` | string | - | Filter by scope (Identity, Brand, Monitoring, Discovery) |
| `startDate` | number | - | Start timestamp in microseconds |
| `endDate` | number | - | End timestamp in microseconds |
| `page` | number | 1 | Page number |
| `limit` | number | 20 | Items per page |
**Response**:
```json
{
"items": [
{
"id": "0c3dddad-ff20-5516-9040-e1647dee7c4b",
"userId": "",
"scope": "Task",
"operation": "Create",
"description": "Task created: TechStart Marketplace Monitor",
"resourceId": "f4ac4f7a-8b19-5793-9c87-258df398e9e4",
"resourceType": "Task",
"brandId": "beae4937-bf6e-55a8-864b-f56cd63bae95",
"timestamp": 1700000000000000
}
],
"total": 10,
"page": 1,
"limit": 20
}
```
**Test Account**: `system-administrator@ext.iptwins.com` or `admin-no2fa@ext.iptwins.com`
---
### POST /audit-logs/export
**Purpose**: Exports audit logs to a downloadable file (CSV/XLSX).
**When to Use**:
- Compliance reporting
- External audit requirements
- Data backup/archival
- Offline analysis
**Authorization**: `system-administrator` role only
**Request Headers**:
```
Authorization: Bearer {accessToken}
Content-Type: application/json
```
**Request Body**:
```json
{
"startDate": 1700000000000000,
"endDate": 1710000000000000,
"requesterId": "76554c74-a127-5cdb-a39c-74e49d15c4c0"
}
```
| Field | Type | Required | Description |
|:------|:-----|:---------|:------------|
| `startDate` | number | Yes | Start timestamp in microseconds |
| `endDate` | number | Yes | End timestamp in microseconds |
| `requesterId` | UUID | Yes | ID of user requesting export |
**Response**:
```json
{
"url": "https://storage.googleapis.com/bucket/exports/audit-logs-2024-01-24.xlsx?token=..."
}
```
**Test Account**: `system-administrator@ext.iptwins.com` or `admin-no2fa@ext.iptwins.com`
---
### GET /tasks/:taskId/logs
**Purpose**: Retrieves audit logs for a specific monitoring task.
**When to Use**:
- Viewing task operation history
- Debugging task issues
- Auditing task configuration changes
**Authorization**:
- `system-administrator` or `account-manager`: Full access
- Other roles: Must have access to the task's brand
**Request Headers**:
```
Authorization: Bearer {accessToken}
```
**Path Parameters**:
| Parameter | Type | Description |
|:----------|:-----|:------------|
| `taskId` | UUID | Monitoring task ID |
**Query Parameters**:
| Parameter | Type | Default | Description |
|:----------|:-----|:--------|:------------|
| `page` | number | 1 | Page number |
| `limit` | number | 20 | Items per page |
**Response**:
```json
{
"items": [
{
"id": "0c3dddad-ff20-5516-9040-e1647dee7c4b",
"scope": "Task",
"operation": "Create",
"description": "Task created: TechStart Marketplace Monitor",
"resourceId": "f4ac4f7a-8b19-5793-9c87-258df398e9e4",
"resourceType": "Task",
"brandId": "beae4937-bf6e-55a8-864b-f56cd63bae95",
"timestamp": 1700000000000000
}
],
"total": 1,
"page": 1,
"limit": 20
}
```
**Test Account**:
- TechStart Inc task: `external-partner@ext.iptwins.com`
- Any brand: `account-manager@ext.iptwins.com` or `admin-no2fa@ext.iptwins.com`
---
### GET /phases/:phaseId/logs
**Purpose**: Retrieves audit logs for a specific phase.
**When to Use**:
- Viewing phase configuration history
- Debugging phase issues
- Auditing phase changes
**Authorization**:
- `system-administrator` or `account-manager`: Full access
- Other roles: Must have access to the phase's brand
**Request Headers**:
```
Authorization: Bearer {accessToken}
```
**Path Parameters**:
| Parameter | Type | Description |
|:----------|:-----|:------------|
| `phaseId` | UUID | Phase ID |
**Query Parameters**:
| Parameter | Type | Default | Description |
|:----------|:-----|:--------|:------------|
| `page` | number | 1 | Page number |
| `limit` | number | 20 | Items per page |
**Test Account**:
- TechStart Inc phase: `external-partner@ext.iptwins.com`
- Any brand: `account-manager@ext.iptwins.com` or `admin-no2fa@ext.iptwins.com`
---
### GET /phases/:phaseId/execution-logs
**Purpose**: Retrieves execution logs (scan operations) for a specific phase.
**When to Use**:
- Monitoring scan execution status
- Debugging crawling issues
- Performance analysis
- AI triage execution tracking
**Authorization**:
- `system-administrator` or `account-manager`: Full access
- Other roles: Must have access to the phase's brand
**Request Headers**:
```
Authorization: Bearer {accessToken}
```
**Path Parameters**:
| Parameter | Type | Description |
|:----------|:-----|:------------|
| `phaseId` | UUID | Phase ID |
**Query Parameters**:
| Parameter | Type | Default | Description |
|:----------|:-----|:--------|:------------|
| `page` | number | 1 | Page number |
| `limit` | number | 20 | Items per page |
| `status` | string | - | Filter by status (Completed, Failed, Running) |
| `startDate` | number | - | Filter by start date |
| `endDate` | number | - | Filter by end date |
**Response**:
```json
{
"items": [
{
"id": "ed9f6488-0035-5723-994c-46cec8681ddf",
"taskId": "f4ac4f7a-8b19-5793-9c87-258df398e9e4",
"phaseId": "4715a97a-e262-5e76-9d04-789b9c5fb14c",
"brandId": "beae4937-bf6e-55a8-864b-f56cd63bae95",
"executionType": "Scan",
"status": "Completed",
"startedAt": 1700000000000000,
"endedAt": 1700000060000000,
"durationMs": 60000,
"itemsProcessed": 150
}
],
"total": 2,
"page": 1,
"limit": 20
}
```
**Test Account**:
- TechStart Inc phase: `external-partner@ext.iptwins.com`
- Any brand: `account-manager@ext.iptwins.com` or `admin-no2fa@ext.iptwins.com`
---
### GET /findings/:id/logs
**Purpose**: Retrieves audit logs for a specific finding.
**When to Use**:
- Viewing finding processing history
- Tracking status changes
- Auditing classification and labeling
- Takedown request history
**Authorization**:
- `system-administrator` or `account-manager`: Full access
- Other roles: Must have access to the finding's brand
**Request Headers**:
```
Authorization: Bearer {accessToken}
```
**Path Parameters**:
| Parameter | Type | Description |
|:----------|:-----|:------------|
| `id` | UUID | Finding ID |
**Query Parameters**:
| Parameter | Type | Default | Description |
|:----------|:-----|:--------|:------------|
| `page` | number | 1 | Page number |
| `limit` | number | 20 | Items per page |
**Test Account**:
- TechStart Inc finding: `external-partner@ext.iptwins.com`
- Any brand: `account-manager@ext.iptwins.com` or `admin-no2fa@ext.iptwins.com`
---
### GET /findings/:findingId/execution-logs
**Purpose**: Retrieves execution logs (retain operations) for a specific finding.
**When to Use**:
- Tracking finding processing status
- Debugging finding retention issues
- Performance analysis
**Authorization**:
- `system-administrator` or `account-manager`: Full access
- Other roles: Must have access to the finding's brand
**Request Headers**:
```
Authorization: Bearer {accessToken}
```
**Path Parameters**:
| Parameter | Type | Description |
|:----------|:-----|:------------|
| `findingId` | UUID | Finding ID |
**Query Parameters**:
| Parameter | Type | Default | Description |
|:----------|:-----|:--------|:------------|
| `page` | number | 1 | Page number |
| `limit` | number | 20 | Items per page |
**Response**:
```json
{
"items": [
{
"id": "bd66cb6a-f4c1-5b6c-8b59-18e8555c080b",
"taskId": "f4ac4f7a-8b19-5793-9c87-258df398e9e4",
"findingId": "58f637c3-a864-56fd-8bab-bb03dc75d0b0",
"brandId": "beae4937-bf6e-55a8-864b-f56cd63bae95",
"executionType": "Retain",
"status": "Completed",
"startedAt": 1700000100000000,
"endedAt": 1700000105000000,
"durationMs": 5000,
"itemsProcessed": 1
}
],
"total": 1,
"page": 1,
"limit": 20
}
```
**Test Account**:
- TechStart Inc finding: `external-partner@ext.iptwins.com`
- Any brand: `account-manager@ext.iptwins.com` or `admin-no2fa@ext.iptwins.com`
---
## Quick Reference: Entity IDs for Testing
| Entity | Brand | ID | Description |
|:-------|:------|:---|:------------|
| Brand | TechStart Inc | `beae4937-bf6e-55a8-864b-f56cd63bae95` | Test brand |
| Task | TechStart Inc | `f4ac4f7a-8b19-5793-9c87-258df398e9e4` | TechStart Marketplace Monitor |
| Phase | TechStart Inc | `4715a97a-e262-5e76-9d04-789b9c5fb14c` | Q1 2024 |
| Finding | TechStart Inc | `58f637c3-a864-56fd-8bab-bb03dc75d0b0` | Fake TechStart Gadget |
---
## Error Responses
All endpoints return consistent error responses:
```json
{
"error": "Error message description"
}
```
| HTTP Status | Meaning |
|:------------|:--------|
| 400 | Bad Request - Missing or invalid parameters |
| 401 | Unauthorized - Missing or invalid token |
| 403 | Forbidden - Insufficient permissions or brand access |
| 404 | Not Found - Resource does not exist |
| 500 | Internal Server Error |