diff --git a/specs/account-management.openapi.yml b/specs/account-management.openapi.yml index e0083b7..e14684c 100644 --- a/specs/account-management.openapi.yml +++ b/specs/account-management.openapi.yml @@ -500,6 +500,14 @@ paths: $ref: '#/components/responses/PERMISSION_DENIED' '404': $ref: '#/components/responses/NOT_FOUND' + '422': + description: The access belongs to the account owner, who can't be removed. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + example: + errors: You can not remove the owner of the account parameters: - schema: type: integer @@ -746,7 +754,16 @@ paths: '404': $ref: '#/components/responses/NOT_FOUND' '422': - $ref: '#/components/responses/UNPROCESSABLE_ENTITY' + description: |- + The permissions can't be updated: the access belongs to the account owner or to an expired + API token, a permission names a resource that doesn't exist or an invalid or owner access + level, or the update would leave the access with no permissions. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + example: + errors: You can't update the permissions of an account owner parameters: - schema: type: integer @@ -1246,7 +1263,28 @@ paths: '403': $ref: '#/components/responses/PERMISSION_DENIED' '422': - $ref: '#/components/responses/UNPROCESSABLE_ENTITY' + description: |- + The token wasn't created. Validation errors of the token itself (no permissions, the + account's active token limit, the name or expiration) come per attribute; an invalid + permission (an unknown resource, an invalid or owner access level) comes as a single + message. + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/UnprocessableEntity' + - $ref: '#/components/schemas/ErrorResponse' + examples: + validation_errors: + summary: The token is invalid + value: + errors: + base: + - No permissions selected. Please choose at least one. + invalid_permission: + summary: A permission is invalid + value: + errors: "Resource of type 'project' and ID #123 not found" '/api/api_tokens/{id}': get: operationId: getApiToken @@ -2181,11 +2219,21 @@ paths: example: errors: Access forbidden '422': - description: Unprocessable entity - validation errors. + description: |- + The sub account wasn't created: the organization reached its sub-account limit or is + scheduled for deletion, or the account is invalid (e.g. a name longer than 80 characters). content: application/json: schema: - $ref: '#/components/schemas/UnprocessableEntity' + type: object + properties: + errors: + type: array + items: + type: string + example: + errors: + - Accounts limit reached parameters: - $ref: '#/components/parameters/organization_id' '/api/organizations/{organization_id}/sub_accounts/{sub_account_id}': diff --git a/specs/email-campaigns.openapi.yml b/specs/email-campaigns.openapi.yml index 33b4955..e08c30c 100644 --- a/specs/email-campaigns.openapi.yml +++ b/specs/email-campaigns.openapi.yml @@ -55,6 +55,17 @@ paths: $ref: "#/components/responses/UNAUTHENTICATED" "403": $ref: "#/components/responses/PERMISSION_DENIED" + "422": + description: The `token` is too large to paginate with — its offset overflows a 64-bit integer. + content: + application/json: + schema: + type: object + properties: + errors: + type: string + example: + errors: token is out of range "429": $ref: "#/components/responses/RATE_LIMITED" x-codeSamples: @@ -992,7 +1003,7 @@ paths: "404": $ref: "#/components/responses/NOT_FOUND" "422": - $ref: "#/components/responses/ACTION_VALIDATION_ERROR" + $ref: "#/components/responses/SENDING_ACTION_VALIDATION_ERROR" "429": $ref: "#/components/responses/RATE_LIMITED" x-codeSamples: @@ -1137,7 +1148,7 @@ paths: "404": $ref: "#/components/responses/NOT_FOUND" "422": - $ref: "#/components/responses/ACTION_VALIDATION_ERROR" + $ref: "#/components/responses/SENDING_ACTION_VALIDATION_ERROR" "429": $ref: "#/components/responses/RATE_LIMITED" x-codeSamples: @@ -2390,7 +2401,8 @@ components: type: string example: news from_display_name: - type: string + type: [string, "null"] + description: Display name shown in the From header. `null` when the campaign has none. example: Acme Marketing reply_to: $ref: "#/components/schemas/ReplyTo" @@ -2752,20 +2764,11 @@ components: - can't be blank ActionValidationErrorResponse: type: object - description: |- - Validation error returned by the lifecycle action endpoints. `errors` is either a single - message (an invalid state transition or an invalid `datetime`) or a list of messages - (sending-validation failures). + description: A lifecycle action's validation error as a single message, such as an invalid state transition. properties: errors: - oneOf: - - type: string - example: "Cannot transition from 'started' to 'scheduled'" - - type: array - items: - type: string - example: - - Campaign design can't be blank + type: string + example: "Cannot transition from 'under_review' to 'draft'" responses: EmailCampaignsResponse: description: A paginated list of email campaigns. @@ -2859,13 +2862,33 @@ components: schema: $ref: "#/components/schemas/ValidationErrorResponse" ACTION_VALIDATION_ERROR: - description: |- - The lifecycle action was rejected — the campaign was in a state that does not allow the - action, the `datetime` was invalid, or sending validation failed. + description: The lifecycle action was rejected — the campaign was in a state that does not allow the action. content: application/json: schema: $ref: "#/components/schemas/ActionValidationErrorResponse" + SENDING_ACTION_VALIDATION_ERROR: + description: |- + The campaign wasn't started or scheduled — it was in a state that does not allow the + action or the `datetime` was invalid (a single message), or sending validation failed + (messages per attribute, campaign-wide ones under `base`). + content: + application/json: + schema: + oneOf: + - $ref: "#/components/schemas/ActionValidationErrorResponse" + - $ref: "#/components/schemas/ValidationErrorResponse" + examples: + invalid_transition: + summary: The campaign can't be started or scheduled from its state + value: + errors: "Cannot transition from 'started' to 'scheduled'" + sending_validation: + summary: Sending validation failed + value: + errors: + base: + - Your account has no company information. Add it in the account settings ("Company Information" tab) before sending. RATE_LIMITED: description: |- Too many requests. The public API is rate limited to 150 requests per 10 seconds per diff --git a/specs/email-sending.openapi.yml b/specs/email-sending.openapi.yml index 50cc099..edc882b 100644 --- a/specs/email-sending.openapi.yml +++ b/specs/email-sending.openapi.yml @@ -719,6 +719,16 @@ paths: $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' + '422': + description: The domain can't be deleted while inbound inboxes use it. + content: + application/json: + schema: + $ref: '#/components/schemas/UnprocessableEntity' + example: + errors: + base: + - Can't delete the domain because there are inbound inboxes depending on it. patch: summary: Update domain @@ -1005,7 +1015,29 @@ paths: '404': $ref: '#/components/responses/NotFound' '422': - $ref: '#/components/responses/UnprocessableEntity' + description: |- + The instructions weren't sent: the email address is invalid, or the domain is blocked + although its DNS records are verified. Each key holds a single message. + content: + application/json: + schema: + type: object + properties: + errors: + type: object + additionalProperties: + type: string + examples: + invalid_email: + summary: The email address is invalid + value: + errors: + email: Invalid email address + domain_not_eligible: + summary: The domain is blocked + value: + errors: + base: Domain is not eligible to send emails /api/domains/{domain_id}/company_info: get: