{
  "openapi": "3.1.0",
  "info": {
    "title": "Journal Entry API 1.0",
    "description": "API for managing journal entries in the Adra Product Suite.",
    "version": "1.0",
    "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"
    }
  },
  "tags": [
    {
      "name": "JournalEntries",
      "description": "Operations for managing journal entries and their states"
    }
  ],
  "servers": [
    {
      "url": "https://journal.adra.com",
      "description": "Production server"
    },
    {
      "url": "https://journal.adrastage.com",
      "description": "Stage server"
    },
    {
      "url": "https://journal.adratest.com",
      "description": "Test server"
    },
    {
      "url": "https://journal.adradev.com",
      "description": "Dev server"
    }
  ],
  "externalDocs": {
    "description": "Adra Success Center",
    "url": "https://success.adra.com/s/knowledge-center"
  },
  "paths": {
    "/api/v1.0/engagements/{engagementSid}/journal-entries": {
      "get": {
        "tags": ["JournalEntries"],
        "summary": "Get journal entries",
        "description": "OData endpoint that gets journal entries",
        "operationId": "GetJournalEntries",
        "parameters": [
          {
            "name": "engagementSid",
            "in": "path",
            "description": "The engagement SID",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "$filter",
            "in": "query",
            "description": "OData $filter parameter",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "$orderby",
            "in": "query",
            "description": "OData $orderby parameter",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "$top",
            "in": "query",
            "description": "OData $top parameter",
            "required": true,
            "schema": {
              "maximum": 5000,
              "minimum": 0,
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "$skip",
            "in": "query",
            "description": "OData $skip parameter",
            "schema": {
              "maximum": 5000,
              "minimum": 0,
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "$count",
            "in": "query",
            "description": "OData $count parameter",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JournalEntryReadModelQueryResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "adra_oauth_code_pkce": ["journal_api.public"],
            "adra_oauth_client_cred": ["journal_api.public"],
            "adra_personal_access_token": ["journal_api.public"]
          }
        ]
      }
    },
    "/api/v1.0/engagements/{engagementSid}/journal-entries/command/pendingpost/bulk": {
      "put": {
        "tags": ["JournalEntries"],
        "summary": "Update journals as pending post",
        "description": "Update 'Ready to post' or 'Pending post' or 'Rejected' journals as 'Pending post'",
        "operationId": "MarkJournalsAsPendingPost",
        "parameters": [
          {
            "name": "engagementSid",
            "in": "path",
            "description": "The engagement SID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The details of the journals",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JournalEntriesPendingPostWriteModel"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/JournalUpdatedResult"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "adra_oauth_code_pkce": ["journal_api.public"],
            "adra_oauth_client_cred": ["journal_api.public"],
            "adra_personal_access_token": ["journal_api.public"]
          }
        ]
      }
    },
    "/api/v1.0/engagements/{engagementSid}/journal-entries/command/post/bulk": {
      "put": {
        "tags": ["JournalEntries"],
        "summary": "Update journals as posted",
        "description": "Update 'Ready to post' or 'Pending post' journals as 'Posted' or override the properties of already posted journals",
        "operationId": "AcceptJournals",
        "parameters": [
          {
            "name": "engagementSid",
            "in": "path",
            "description": "The engagement SID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The details of the journals",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JournalEntriesPostedWriteModel"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JournalEntriesAcceptedReadModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "adra_oauth_code_pkce": ["journal_api.public"],
            "adra_oauth_client_cred": ["journal_api.public"],
            "adra_personal_access_token": ["journal_api.public"]
          }
        ]
      }
    },
    "/api/v1.0/engagements/{engagementSid}/journal-entries/command/reject/bulk": {
      "put": {
        "tags": ["JournalEntries"],
        "summary": "Update journals as rejected",
        "description": "Update 'Posted' or 'Pending post' journals as rejected or override the properties of already rejected journals",
        "operationId": "RejectJournal",
        "parameters": [
          {
            "name": "engagementSid",
            "in": "path",
            "description": "The engagement SID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The details of the journals",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JournalEntriesRejectedWriteModel"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/JournalUpdatedResult"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "adra_oauth_code_pkce": ["journal_api.public"],
            "adra_oauth_client_cred": ["journal_api.public"],
            "adra_personal_access_token": ["journal_api.public"]
          }
        ]
      }
    }
  },
  "webhooks": {
    "JournalPublished": {
      "post": {
        "tags": ["Journal Events"],
        "summary": "Journal Published Event",
        "description": "This event is triggered when a journal is published as ready to post",
        "operationId": "JournalPublishedEvent",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook received successfully"
          },
          "default": {
            "description": "Error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "HttpStatusCode": {
        "enum": [
          "Continue",
          "SwitchingProtocols",
          "Processing",
          "EarlyHints",
          "OK",
          "Created",
          "Accepted",
          "NonAuthoritativeInformation",
          "NoContent",
          "ResetContent",
          "PartialContent",
          "MultiStatus",
          "AlreadyReported",
          "IMUsed",
          "MultipleChoices",
          "Ambiguous",
          "MovedPermanently",
          "Moved",
          "Found",
          "Redirect",
          "SeeOther",
          "RedirectMethod",
          "NotModified",
          "UseProxy",
          "Unused",
          "TemporaryRedirect",
          "RedirectKeepVerb",
          "PermanentRedirect",
          "BadRequest",
          "Unauthorized",
          "PaymentRequired",
          "Forbidden",
          "NotFound",
          "MethodNotAllowed",
          "NotAcceptable",
          "ProxyAuthenticationRequired",
          "RequestTimeout",
          "Conflict",
          "Gone",
          "LengthRequired",
          "PreconditionFailed",
          "RequestEntityTooLarge",
          "RequestUriTooLong",
          "UnsupportedMediaType",
          "RequestedRangeNotSatisfiable",
          "ExpectationFailed",
          "MisdirectedRequest",
          "UnprocessableEntity",
          "UnprocessableContent",
          "Locked",
          "FailedDependency",
          "UpgradeRequired",
          "PreconditionRequired",
          "TooManyRequests",
          "RequestHeaderFieldsTooLarge",
          "UnavailableForLegalReasons",
          "InternalServerError",
          "NotImplemented",
          "BadGateway",
          "ServiceUnavailable",
          "GatewayTimeout",
          "HttpVersionNotSupported",
          "VariantAlsoNegotiates",
          "InsufficientStorage",
          "LoopDetected",
          "NotExtended",
          "NetworkAuthenticationRequired"
        ],
        "type": "string"
      },
      "JournalEntriesAcceptedReadModel": {
        "required": ["journalsUpdated", "bundleGuid"],
        "type": "object",
        "properties": {
          "journalsUpdated": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JournalUpdatedResult"
            }
          },
          "bundleGuid": {
            "type": "string",
            "format": "uuid"
          }
        },
        "additionalProperties": false
      },
      "JournalEntriesPendingPostWriteModel": {
        "required": ["journalGuids"],
        "type": "object",
        "properties": {
          "journalGuids": {
            "maxItems": 1000,
            "minItems": 1,
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          }
        },
        "additionalProperties": false
      },
      "JournalEntriesPostedWriteModel": {
        "required": ["journals"],
        "type": "object",
        "properties": {
          "journals": {
            "maxItems": 1000,
            "minItems": 1,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JournalEntryPostedWriteModel"
            }
          },
          "bundleGuid": {
            "type": "string",
            "format": "uuid"
          }
        },
        "additionalProperties": false
      },
      "JournalEntriesRejectedWriteModel": {
        "required": ["journalGuids", "rejectReason"],
        "type": "object",
        "properties": {
          "journalGuids": {
            "maxItems": 1000,
            "minItems": 1,
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "rejectReason": {
            "maxLength": 800,
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "JournalEntryAttachmentReadModel": {
        "required": ["fileName", "downloadLink"],
        "type": "object",
        "properties": {
          "fileName": {
            "type": "string"
          },
          "downloadLink": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "JournalEntryLineReadModel": {
        "required": ["lineNumber", "accountNo", "dimensions"],
        "type": "object",
        "properties": {
          "lineNumber": {
            "type": "integer",
            "format": "int32"
          },
          "accountNo": {
            "type": "string"
          },
          "accountName": {
            "type": "string"
          },
          "credit": {
            "type": "number",
            "format": "double"
          },
          "debit": {
            "type": "number",
            "format": "double"
          },
          "lineText": {
            "type": "string"
          },
          "dimensions": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          }
        },
        "additionalProperties": false
      },
      "JournalEntryPostedWriteModel": {
        "required": ["journalGuid", "erpReference"],
        "type": "object",
        "properties": {
          "journalGuid": {
            "type": "string",
            "format": "uuid"
          },
          "erpReference": {
            "maxLength": 64,
            "type": "string"
          },
          "postComment": {
            "maxLength": 800,
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "JournalEntryReadModel": {
        "required": [
          "engagementGuid",
          "journalGuid",
          "legalEntityName",
          "legalEntityCode",
          "periodEndDate",
          "periodName",
          "description",
          "journalDate",
          "preparedBy",
          "preparedDate",
          "journalStatus",
          "currency",
          "debitSum",
          "creditSum",
          "totalLineCount",
          "lastModifiedDate",
          "journalLines",
          "attachments"
        ],
        "type": "object",
        "properties": {
          "engagementGuid": {
            "type": "string",
            "format": "uuid"
          },
          "journalGuid": {
            "type": "string",
            "format": "uuid"
          },
          "legalEntityName": {
            "type": "string"
          },
          "legalEntityCode": {
            "type": "string"
          },
          "periodEndDate": {
            "type": "string",
            "format": "date-time"
          },
          "periodName": {
            "type": "string"
          },
          "periodCode": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "journalDate": {
            "type": "string",
            "format": "date-time"
          },
          "preparedBy": {
            "type": "string"
          },
          "preparedDate": {
            "type": "string",
            "format": "date-time"
          },
          "journalStatus": {
            "$ref": "#/components/schemas/JournalStatus"
          },
          "currency": {
            "type": "string"
          },
          "debitSum": {
            "type": "number",
            "format": "double"
          },
          "creditSum": {
            "type": "number",
            "format": "double"
          },
          "totalLineCount": {
            "type": "integer",
            "format": "int32"
          },
          "lastModifiedDate": {
            "type": "string",
            "format": "date-time"
          },
          "journalLines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JournalEntryLineReadModel"
            }
          },
          "attachments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JournalEntryAttachmentReadModel"
            }
          }
        },
        "additionalProperties": false
      },
      "JournalEntryReadModelQueryResult": {
        "type": "object",
        "properties": {
          "value": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JournalEntryReadModel"
            }
          },
          "@odata.count": {
            "type": "string"
          },
          "@odata.nextPage": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "JournalStatus": {
        "enum": ["Draft", "ReadyToPost", "PendingPost", "Posted", "Rejected"],
        "type": "string"
      },
      "JournalUpdatedResult": {
        "required": ["journalGuid", "statusCode"],
        "type": "object",
        "properties": {
          "journalGuid": {
            "type": "string",
            "format": "uuid"
          },
          "statusReason": {
            "type": "string"
          },
          "statusCode": {
            "$ref": "#/components/schemas/HttpStatusCode"
          }
        },
        "additionalProperties": false
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer",
            "format": "int32"
          },
          "detail": {
            "type": "string"
          },
          "instance": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "WebhookEvent": {
        "type": "object",
        "properties": {
          "EventId": {
            "type": "string",
            "format": "uuid",
            "description": "Unique Event Identifier"
          },
          "CorrelationId": {
            "type": "string",
            "format": "uuid",
            "description": "Correlation identifier"
          },
          "EventType": {
            "type": "string",
            "description": "Event type"
          },
          "EventMessage": {
            "type": "string",
            "description": "Human-readable event description"
          },
          "CreatedDate": {
            "type": "string",
            "format": "date-time",
            "description": "Time of the event"
          },
          "Payload": {
            "$ref": "#/components/schemas/JournalPublished"
          }
        },
        "required": [
          "EventId",
          "EventType",
          "EventMessage",
          "CreatedDate",
          "Payload"
        ]
      },
      "JournalPublished": {
        "type": "object",
        "properties": {
          "JournalId": {
            "type": "string",
            "format": "uuid",
            "description": "Journal Identifier"
          },
          "ResourceUrl": {
            "type": "string",
            "description": "Resource URL"
          }
        },
        "required": ["JournalId", "ResourceUrl"]
      }
    },
    "securitySchemes": {
      "adra_oauth_code_pkce": {
        "type": "oauth2",
        "description": "OAuth 2.0 JWT Bearer Token Scheme",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://login.adra.com/connect/authorize",
            "tokenUrl": "https://login.adra.com/connect/token",
            "scopes": {
              "journal_api.public": "journal_api.public"
            }
          }
        }
      },
      "adra_oauth_client_cred": {
        "type": "oauth2",
        "description": "Restricted to internal clients. Requires client ID and secret obtained from Adra Engineering. Scopes are mandatory on token requests.",
        "flows": {
          "clientCredentials": {
            "tokenUrl": "https://login.adra.com/connect/token",
            "scopes": {
              "journal_api.public": "journal_api.public"
            }
          }
        }
      },
      "adra_personal_access_token": {
        "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 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"
      }
    }
  }
}
