{
  "openapi": "3.0.1",
  "info": {
    "title": "Setup API 1.0",
    "version": "1.0",
    "description": "API for Audit Trails and Auth Logs from Adra Setup Portal",
    "contact": {
      "name": "API Support",
      "url": "https://success.adra.com/s/",
      "email": "support@adra.com"
    },
    "license": {
      "name": "Proprietary License",
      "url": "https://www.trintech.com/terms-and-conditions/adra/"
    },
    "x-feedbackLink": {
      "url": "https://success.adra.com/s/resources/ideas",
      "label": "Give Feedback"
    }
  },
  "x-topics": [
    {
      "title": "Organization Id",
      "content": "The Organization Identifier to use in these operations can be found under the profile of the user creating the access token. It is located at the top of the page and is referred to as 'Org Sid'. You can access the profile page [here](https://setup.adra.com/profile)."
    },
    {
      "title": "ContinuationTokens",
      "content": "### Save continuation tokens\nA continuation token is a string value that acts as a bookmark for your query's progress. Since query executions are stateless at the server side, these tokens allow you to resume data retrieval from where you left off. As new logs are continuously generated through system usage, the feed will always have more data available in the future.\n\n### Important Considerations\nSometimes queries may return empty pages (no results) even when there are results available on future pages. This can happen due to:\n- Multiple network calls being made in the background\n- Queries taking longer than expected to retrieve documents\n- Data changes occurring between pagination requests\n\n### Best Practices\n- Store the continuation token from the most recent response\n- Use the continuation token to resume fetching new logs in subsequent requests\n- Handle empty pages gracefully by continuing to the next page\n- Implement retry logic for temporary failures while maintaining the same continuation token\n\n### Example Flow\n```\nPage 1: Results + Token A\nPage 2: No Results + Token A\nPage 3: Results + Token B\nPage 4: Empty Results + Token B (Save for future use)\n```"
    }
  ],
  "servers": [
    {
      "url": "https://setup.adra.com",
      "description": "Production server"
    },
    {
      "url": "https://setup.adrastage.com",
      "description": "Stage server"
    },
    {
      "url": "https://setup.adratest.com",
      "description": "Test server"
    },
    {
      "url": "https://setup.adradev.com",
      "description": "Dev server"
    }
  ],
  "tags": [
    {
      "name": "AuditTrails",
      "description": "## Structure\nWe categorize the events into 3 CoreEntity types:\n\n- Organization.\n- Engagement.\n- Operator.\n\n## Audit Trail events:\n- **CoreEntityChange**: Property changes to the main entities (Organization, Operator, Engagement).\n- **ConfigChange**: Configuration changes including:\n  - Password Policy\n  - SAML IdP Config\n  - Operator Credential\n  - Storage Location\n- **LicenceChange**: Changes related to:\n  - Engagement Application\n  - Engagement Active status\n  - Subscription ID changes\n- **OperatorAccessChange**: Access-related changes including:\n  - Operator Engagement Application Role\n  - Operator Engagement\n  - Operator Organization\n- **EngagementOrganizationChange**: Changes to Engagement Organization relationships\n\n## Denormalization\nBecause operations often involve relationships between two core entities (Operator, Organization, Engagement), and these relationships may exist across different organizations (especially for Service Provider Organizations), the data is denormalized at both ends of the relationship. This enables direct auditing by each entity involved.\n\nThe logs include \"ContractedEntity\" and \"ContractedEntityId\" fields to support this.\n\n### Denormalization Examples\n\n**1. Operator-Organization Access Events**\nCreates two records:\n- CoreEntity: Operator -> ContractedEntity: Organization\n- CoreEntity: Organization -> ContractedEntity: Operator\n\n**2. Organization-Engagement Trust Events**\nCreates two records:\n- CoreEntity: Engagement -> ContractedEntity: Organization\n- CoreEntity: Organization -> ContractedEntity: Engagement\n\n**3. Operator-Engagement Access Events**\nCreates two records:\n- CoreEntity: Operator -> ContractedEntity: Engagement\n- CoreEntity: Engagement -> ContractedEntity: Operator\n\n## Message Structure\nEach audit record contains three message-related properties:\n\n- **LogMessageKey**: Resource key for localization\n- **LogMessageParams**: Parameters for message formatting\n- **LogMessage**: Formatted message in English\n\nThis structure enables localization of audit messages in the UI while maintaining a consistent audit record."
    },
    {
      "name": "AuthLogs",
      "description": "### Authentication Events Logged\n- Successful login attempts\n- Failed login attempts (with failed attempt counter)\n- Failed attempt counter resets\n- SAML authentication initiation\n- SAML authentication failures\n\n### Important Notes\n- These logs focus solely on authentication events (proving identity)\n- Application authorization (permissions/access rights) is handled separately within each application after successful OpenID Connect authentication\n- Authorization logs are not included here as they are managed by the respective applications"
    }
  ],
  "externalDocs": {
    "description": "Adra Success Center",
    "url": "https://success.adra.com/s/knowledge-center"
  },
  "paths": {
    "/api/v1.0/organizations/{organizationGuid}/audit-trails": {
      "get": {
        "tags": ["Setup Audit Trails"],
        "summary": "Get the audit trails for an organization",
        "description": "The audit trails are served in batches of less than 100 records at the time and a continuation token.",
        "operationId": "GetOrganizationChangeFeed",
        "parameters": [
          {
            "name": "organizationGuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "continuationToken",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditTrailResponseDto"
                },
                "example": {
                  "continuationToken": "eyJWIjoyLCJSaWQiOiJ6Njk5QUx5UlYzbz0iLCJDb250aW51YXRpb24iOlt7IkZlZWRSYW5nZSI6eyJ0eXBlIjoiTG9naWNhbCBQYXJ0aXRpb24gS2V5IiwidmFsdWUiOiJbXCI3ZWI2YzE0NS1iNmQyLTRkNjctOGUyMC02Zjg3Y2E5NDJiN2ZcIl0ifSwiU3RhdGUiOnsidHlwZSI6ImNvbnRpbnVhdGlvbiIsInZhbHVlIjoiXCIxOTUxOTZcIiJ9fV19",
                  "responseData": [
                    {
                      "id": "7d94882a-ee8e-4741-b461-4fdbc731362b",
                      "organizationId": "7eb6c145-b6d2-4d67-8e20-6f87ca942b7f",
                      "auditEvent": "CoreEntityChange",
                      "auditEntity": "Organization",
                      "auditAction": "Updated",
                      "coreEntity": "Organization",
                      "coreEntityId": "7eb6c145-b6d2-4d67-8e20-6f87ca942b7f",
                      "contractedEntity": null,
                      "contractedEntityId": null,
                      "timestamp": "2024-03-15T14:48:51+00:00",
                      "oldValue": null,
                      "newValue": null,
                      "diff": [
                        {
                          "prop": "Domain",
                          "oldVal": null,
                          "newVal": "updatedDomain@tenant.com"
                        },
                        {
                          "prop": "Name",
                          "oldVal": "Demo Organization",
                          "newVal": "The Organization"
                        }
                      ],
                      "author": {
                        "authorId": "bf5c2988-f6d8-4108-87b1-e1bdcf296d33",
                        "authorName": "Anders Reyes",
                        "authorOrgId": "e6c779ff-9401-4915-b74d-ca4b937c7de5",
                        "authorOrgName": "My Organization",
                        "ipAddress": "213.52.72.214"
                      },
                      "message": {
                        "logMessage": "Organization updated",
                        "logMessageKey": "OrganizationUpdated",
                        "logMessageParams": ""
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "HttpBearerToken": ["setup_api.public"]
          }
        ]
      }
    },
    "/api/v1.0/organizations/{organizationGuid}/auth-logs": {
      "get": {
        "tags": ["Setup Audit Trails"],
        "summary": "Get the employee auth logs for an organization",
        "description": "The auth logs are served in batches of less than 100 records at the time and a continuation token.",
        "operationId": "GetOrganizationAuthLogsChangeFeed",
        "parameters": [
          {
            "name": "organizationGuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "continuationToken",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthLogResponseDto"
                },
                "example": {
                  "continuationToken": "W3sidG9rZW4iOiIrUklEOn56Njk5QUtzeTZMTkJuUkFBQUFBQUFBPT0jUlQ6MSNUUkM6MTAwI1JURDpIUEpKbUtUMXVacWxCQm5HeU5TT0JNSFoxWTExOUE9PSNJU1Y6MiNJRU86NjU1NjcjUUNGOjgiLCJyYW5nZSI6eyJtaW4iOiIiLCJtYXgiOiJGRiJ9fV0",
                  "responseData": [
                    {
                      "id": "2954e17e-bfbb-4150-86b3-beb659957968",
                      "unknownSub": null,
                      "ipAddress": "175.157.136.231",
                      "organizationId": "15f1e221-37c4-4095-a0de-88583cb5e7aa",
                      "operatorId": "f039261c-bf9f-4dfc-829c-dde8601a12ed",
                      "authEvent": "Authentication",
                      "authAction": "LoginSuccess",
                      "logLevel": "Info",
                      "attributes": {
                        "sub": "HCY58J-__E2CnN3oYBoS7Q",
                        "clientId": "setup_app",
                        "username": "myuser@gmail.com",
                        "requireConsent": false,
                        "consentShown": false,
                        "scopes": "openid,profile,setup_api.full_access,login_api.personal_tokens,login_api.resources,integrationhub_api.upload"
                      },
                      "message": {
                        "logMessage": "LoginSuccess",
                        "logMessageKey": "LoginSuccess",
                        "logMessageParams": null
                      },
                      "timestamp": "2024-11-04T07:45:06+00:00"
                    },
                    {
                      "id": "69c06977-897c-4f52-9611-e30e209f169e",
                      "unknownSub": "myuser@gmail.com",
                      "ipAddress": null,
                      "organizationId": "15f1e221-37c4-4095-a0de-88583cb5e7aa",
                      "operatorId": "f039261c-bf9f-4dfc-829c-dde8601a12ed",
                      "authEvent": "Authentication",
                      "authAction": "ApplicationLoginTimestamp",
                      "logLevel": "Info",
                      "attributes": {
                        "application": "Setup"
                      },
                      "message": {
                        "logMessage": "ApplicationLoginTimestamp",
                        "logMessageKey": "ApplicationLoginTimestamp",
                        "logMessageParams": null
                      },
                      "timestamp": "2024-11-04T07:45:06+00:00"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "HttpBearerToken": ["setup_api.public"]
          }
        ]
      }
    },
    "/api/v1.0/organizations/{organizationGuid}/audit-trails/status": {
      "get": {
        "tags": ["Setup Audit Trails"],
        "summary": "Check if more audit trail changes are available",
        "description": "Useful for automations that check if there is new available data before retrieval. Requires continuationToken. Admin access required.",
        "operationId": "GetOrganizationChangeFeedStatus",
        "parameters": [
          {
            "name": "organizationGuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "continuationToken",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChangeFeedStatusDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "HttpBearerToken": ["setup_api.public"]
          }
        ]
      }
    },
    "/api/v1.0/organizations/{organizationGuid}/auth-logs/status": {
      "get": {
        "tags": ["Setup Audit Trails"],
        "summary": "Check if more auth log changes are available",
        "description": "Useful for automations that check if there is new available data before retrieval. Requires continuationToken. Admin access required.",
        "operationId": "GetOrganizationAuthLogsChangeFeedStatus",
        "parameters": [
          {
            "name": "organizationGuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "continuationToken",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChangeFeedStatusDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "HttpBearerToken": ["setup_api.public"]
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "AuditTrailDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "organizationId": {
            "type": "string"
          },
          "auditEvent": {
            "type": "string"
          },
          "auditEntity": {
            "type": "string"
          },
          "auditAction": {
            "type": "string"
          },
          "coreEntity": {
            "type": "string"
          },
          "coreEntityId": {
            "type": "string",
            "format": "uuid"
          },
          "contractedEntity": {
            "type": "string",
            "nullable": true
          },
          "contractedEntityId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "oldValue": {
            "type": "object",
            "nullable": true
          },
          "newValue": {
            "type": "object",
            "nullable": true
          },
          "diff": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Change"
            },
            "nullable": true
          },
          "author": {
            "$ref": "#/components/schemas/Author"
          },
          "message": {
            "$ref": "#/components/schemas/AuditTrailMessage"
          }
        },
        "additionalProperties": false
      },
      "AuditTrailResponseDto": {
        "type": "object",
        "properties": {
          "continuationToken": {
            "type": "string",
            "nullable": true
          },
          "responseData": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AuditTrailDto"
            },
            "nullable": true
          },
          "hasMoreChanges": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "AuthLogDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "unknownSub": {
            "type": "string",
            "nullable": true
          },
          "ipAddress": {
            "type": "string",
            "nullable": true
          },
          "organizationId": {
            "type": "string"
          },
          "operatorId": {
            "type": "string"
          },
          "authEvent": {
            "type": "string"
          },
          "authAction": {
            "type": "string"
          },
          "logLevel": {
            "type": "string",
            "nullable": true
          },
          "attributes": {
            "type": "object",
            "nullable": true
          },
          "message": {
            "$ref": "#/components/schemas/AuthLogMessage"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "AuthLogResponseDto": {
        "type": "object",
        "properties": {
          "continuationToken": {
            "type": "string",
            "nullable": true
          },
          "responseData": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AuthLogDto"
            },
            "nullable": true
          },
          "hasMoreChanges": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "Author": {
        "type": "object",
        "properties": {
          "authorId": {
            "type": "string",
            "format": "uuid"
          },
          "authorName": {
            "type": "string"
          },
          "authorOrgId": {
            "type": "string",
            "format": "uuid"
          },
          "authorOrgName": {
            "type": "string"
          },
          "ipAddress": {
            "type": "string"
          }
        },
        "additionalProperties": false,
        "nullable": true
      },
      "Change": {
        "type": "object",
        "properties": {
          "prop": {
            "type": "string"
          },
          "oldVal": {},
          "newVal": {}
        },
        "additionalProperties": false
      },
      "ChangeFeedStatusDto": {
        "type": "object",
        "properties": {
          "hasMoreChanges": {
            "type": "boolean"
          },
          "continuationToken": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AuditTrailMessage": {
        "type": "object",
        "properties": {
          "logMessage": {
            "type": "string"
          },
          "logMessageKey": {
            "type": "string",
            "nullable": true
          },
          "logMessageParams": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "nullable": true
      },
      "AuthLogMessage": {
        "type": "object",
        "properties": {
          "logMessage": {
            "type": "string"
          },
          "logMessageKey": {
            "type": "string",
            "nullable": true
          },
          "logMessageParams": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "detail": {
            "type": "string",
            "nullable": true
          },
          "instance": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      }
    },
    "securitySchemes": {
      "HttpBearerToken": {
        "type": "http",
        "description": "This API uses OAuth 2.0 Bearer tokens for authentication.\n\n**Authentication Token**: You can obtain a token using:\n   - **Personal Access Tokens**: Generate these tokens for \"Identity\" from your [user account settings](https://setup.adra.com/profile/access)\n\nOnce you have a token, include it in the `Authorization` header of your requests:\n\n```\nAuthorization: Bearer YOUR_TOKEN_HERE\n```\n\nEnsure that you keep your tokens secure and do not share them publicly.",
        "scheme": "Bearer"
      }
    }
  }
}
