skapi-js 2.2.6-beta.0 → 2.2.6-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/skapi.d.mts CHANGED
@@ -296,6 +296,13 @@ type Newsletter = {
296
296
  * A number for the 0 ~ 99 groups, the group name for a named newsletter group.
297
297
  */
298
298
  group: number | string;
299
+ /**
300
+ * true: mailed to the group's dry address, so it is stored and was sent to nobody. The
301
+ * Newsletters page's Send button, or a ticket's Send newsletter action, sends it later.
302
+ */
303
+ dry?: boolean;
304
+ /** When the Send button or a ticket's Send newsletter action sent it, in ms. Absent on a newsletter that went out by e-mail. */
305
+ sent?: number;
299
306
  };
300
307
  type NewsletterGroup = {
301
308
  /** Name of the newsletter group. */
@@ -716,7 +723,7 @@ type TicketConditionRow = {
716
723
  * Where the row looks, relative to its own list and written without `${ }`:
717
724
  * - `data` rows: a path into the request body. "id" is the body's `id`, "order[id]" is `order.id`.
718
725
  * - `params` rows: a path into the query string, read the same way.
719
- * - `data` rows of a req action's response condition: a path into the response body ("status" is the response's `status`).
726
+ * - `response` rows of a cond action: a path into the enclosing action's answer ("body[status]" is a response's body.status, "record_id" a posted record's id); "" is the whole answer as text.
720
727
  * - `headers` rows: the header name, matched case-insensitively.
721
728
  * - `user` rows: the consumer attribute name.
722
729
  *
@@ -838,11 +845,10 @@ type TicketCondition = {
838
845
  record_access?: string;
839
846
  };
840
847
  /**
841
- * What a `req` action checks on the response before its nested actions run: `headers` and
842
- * `data` rows work as in the ticket's condition (captures and `setValueWhenMatch` included).
843
- * `headers` rows read the response headers and `data` row keys are paths into the parsed
844
- * response body. `user` and `record_access` still check the consumer, so they only work for
845
- * signed requests. A response that is not 2xx fails before this is checked.
848
+ * Skapi's own billing rows only (the super master registers them): the response check a `req`
849
+ * carried before 2026-10-09. Anyone else checks a response with a cond action in the req's
850
+ * Then chain. `headers` rows read the response headers and `data` row keys are paths into the
851
+ * parsed body; `user` and `record_access` check the consumer.
846
852
  */
847
853
  type TicketResponseCondition = Pick<TicketCondition, 'headers' | 'data' | 'user' | 'record_access'>;
848
854
  /**
@@ -864,7 +870,7 @@ type TicketResponseCondition = Pick<TicketCondition, 'headers' | 'data' | 'user'
864
870
  * | `${user}`, `${user[key]}` | The signed-in user's attributes. Signed requests only. |
865
871
  * | `${ip}`, `${user_agent}`, `${method}` | The caller's IP address, User-Agent and HTTP method. |
866
872
  * | `${record_access}` | The record ID the condition's `record_access` names. Signed requests only. |
867
- * | `${response}`, `${response[key]}` | The answer of the enclosing action, in its Then chain (`actions`) and the `err` chains inside it: the record a pstr posted, the parsed body of a req's response, the SUCCESS text of acsg and acsr. |
873
+ * | `${response}`, `${response[key]}` | The answer of the enclosing action, in its Then chain (`actions`) and the `err` chains inside it: the record a pstr posted, the response of a req ({ status, headers, body }), the SUCCESS text of acsg, acsr, mail and nlsd. |
868
874
  * | `${error}`, `${error[key]}` | In an `err` chain, the failure: `code`, `message`, `detail`, `action` (the act) and `path`. |
869
875
  * | `${ticket}`, `${ticket[key]}` | This consumption: `id`, `service`, `owner`, `consume_id`, `timestamp` and `hash`. |
870
876
  * | `${CLIENT_SECRET}` | Reserved. See `secretName` on the req action. |
@@ -872,18 +878,19 @@ type TicketResponseCondition = Pick<TicketCondition, 'headers' | 'data' | 'user'
872
878
  * Registration refuses anything else inside `${ }` (an unknown root such as `${id}`, keys under
873
879
  * a root that takes none such as `${ip[x]}`, `${placeholder}` or `${headers}` without a key,
874
880
  * broken brackets) with a message listing these forms, `${result}` (gone: an answer is read as
875
- * `${response}` in the action's Then chain, or captured by its Check), and a reference written
881
+ * `${response}` in the action's Then chain, or captured there by a Condition action), and a reference written
876
882
  * where it can never resolve (`${response}` outside a Then chain, `${error}` outside an `err`
877
883
  * chain, `${record_access}` when the condition names no record). When the action runs, a
878
884
  * reference that does not resolve fails it before it does anything: PATH_NOT_FOUND,
879
885
  * PLACEHOLDER_MISSING for a placeholder that was never captured, or AUTH_REQUIRED for `${user}`
880
886
  * on a request that is not signed in. Its `err` chain runs and the consumption stops.
881
887
  *
882
- * Every action but resp and cond answers something (the record, the response body, a SUCCESS
883
- * text) and may carry a Check (`condition`: rows on that answer, a key "" the whole text; a miss
884
- * fails the action) and a Then chain (`actions`, reading the answer as `${response}`). `retry:
885
- * true` on acsg, acsr, pstr and req tries a failure again, up to 3 more times, 1, 2 and 4
886
- * seconds apart, while the time budget holds them; never for a failure inside Then.
888
+ * Every action but resp and cond answers something (the record, the response as { status, headers, body }, a SUCCESS
889
+ * text) and may carry a Then chain (`actions`, reading the answer as `${response}`). A Condition
890
+ * action in that chain checks the answer: its `response` rows read it whole (key "") or by key,
891
+ * whatever its shape. `retry: true` on acsg, acsr, pstr, req, mail and nlsd tries a failure again,
892
+ * up to 3 more times, 1, 2 and 4 seconds apart, while the time budget holds them; never for a
893
+ * failure inside Then.
887
894
  */
888
895
  type TicketAction = {
889
896
  /** Set the access group of a user. Answers the SUCCESS text the grant returns. */
@@ -893,8 +900,6 @@ type TicketAction = {
893
900
  group: number | 'admin' | `${string}\${${string}}${string}`;
894
901
  /** Blank = the consumer (signed-in consumption only). The project owner cannot be a target. */
895
902
  user_id?: string;
896
- /** The Check: rows on the answer. */
897
- condition?: TicketAnswerCondition;
898
903
  /** The Then chain, reading the answer as `${response}`. */
899
904
  actions?: TicketAction[];
900
905
  };
@@ -908,7 +913,6 @@ type TicketAction = {
908
913
  record_id: string;
909
914
  /** Blank = the consumer. */
910
915
  user_id?: string | string[];
911
- condition?: TicketAnswerCondition;
912
916
  actions?: TicketAction[];
913
917
  };
914
918
  err?: TicketAction[];
@@ -936,15 +940,13 @@ type TicketAction = {
936
940
  source?: PostRecordConfig['source'];
937
941
  /** Post as this user instead of the project owner. */
938
942
  user_id?: string;
939
- /** The Check: rows on the record posted, such as `record_id`. */
940
- condition?: TicketAnswerCondition;
941
943
  /** The Then chain, reading the record as `${response}` (`${response[record_id]}`). */
942
944
  actions?: TicketAction[];
943
945
  };
944
946
  err?: TicketAction[];
945
947
  retry?: boolean;
946
948
  } | {
947
- /** HTTP request with its own response condition and nested chain. Answers the parsed response body. */
949
+ /** HTTP request with a nested chain on its response. Answers the whole response: { status, headers, body }. */
948
950
  act: 'req';
949
951
  exe: {
950
952
  /**
@@ -1009,13 +1011,56 @@ type TicketAction = {
1009
1011
  };
1010
1012
  /** Legacy. Registration moves these rows to the end of `condition.data`. */
1011
1013
  match?: TicketConditionRow[];
1012
- /** Checked against the response. Captures land in the shared placeholder pool. See TicketResponseCondition. */
1014
+ /** Skapi's own billing rows only. A response check is a Condition action in `actions`, whose `response` rows read the answer. */
1013
1015
  condition?: TicketResponseCondition;
1014
1016
  /**
1015
- * Nested chain, run when the response passes `condition`. It reads the response body
1016
- * as `${response}` and `${response[key]}`, while `${data}` is still the incoming
1017
- * request body. Any action can nest, including another req with its own `secretName`.
1017
+ * Nested chain, run on an answer below 300. It reads the response as `${response}`:
1018
+ * `${response[status]}`, `${response[headers][content-type]}` (header names in
1019
+ * lowercase) and `${response[body][key]}`, while `${data}` is still the incoming
1020
+ * request body. A cond in it checks the response. Any action can nest, including
1021
+ * another req with its own `secretName`.
1022
+ */
1023
+ actions?: TicketAction[];
1024
+ };
1025
+ err?: TicketAction[];
1026
+ retry?: boolean;
1027
+ } | {
1028
+ /**
1029
+ * Send e-mail: one e-mail from a CUSTOM template of the project (the Custom tab of the
1030
+ * Automated Emails page) to one address, from the project's alias. Counts as one e-mail
1031
+ * send (the plan's monthly sends, the Free owner cap and the complaint shutoff apply; a
1032
+ * refusal is QUOTA_EXCEEDED). Answers "SUCCESS: E-mail sent to <address>."
1033
+ */
1034
+ act: 'mail';
1035
+ exe: {
1036
+ /** The template's ID, as the Custom tab and the upload reply show it. Literal; it must be stored when the ticket is registered. */
1037
+ template: string;
1038
+ /** The recipient: one address, or a reference that gives one, such as "${user[email]}" or "${data[email]}". */
1039
+ to: string;
1040
+ /**
1041
+ * Values for the placeholders the template carries, by name: { "order": "${data[order][id]}" } fills
1042
+ * ${order}. Templated. "service_name" and "email" (the recipient) are filled by default and may be
1043
+ * overwritten here. Up to 30.
1018
1044
  */
1045
+ placeholders?: {
1046
+ [name: string]: string | number | boolean;
1047
+ };
1048
+ actions?: TicketAction[];
1049
+ };
1050
+ err?: TicketAction[];
1051
+ retry?: boolean;
1052
+ } | {
1053
+ /**
1054
+ * Send newsletter: a stored newsletter of a group, dry or already sent, to every subscriber of the
1055
+ * group, the way an e-mailed newsletter goes out (one e-mail send per subscriber, same gates).
1056
+ * Answers "SUCCESS: Newsletter sent to the subscribers of <group>."
1057
+ */
1058
+ act: 'nlsd';
1059
+ exe: {
1060
+ /** "public", "authorized", a number from 2 to 99, or a named group. Literal. */
1061
+ group: 'public' | 'authorized' | number | string;
1062
+ /** The newsletter's message_id (getNewsletters()). Literal; it must be stored under the group when the ticket is registered. */
1063
+ newsletter: string;
1019
1064
  actions?: TicketAction[];
1020
1065
  };
1021
1066
  err?: TicketAction[];
@@ -1052,27 +1097,16 @@ type TicketAction = {
1052
1097
  */
1053
1098
  act: 'cond';
1054
1099
  exe: {
1055
- data?: TicketConditionRow[];
1056
- params?: TicketConditionRow[];
1057
- headers?: TicketCondition['headers'];
1058
- ip?: TicketCondition['ip'];
1059
- user_agent?: TicketCondition['user_agent'];
1060
- user?: TicketCondition['user'];
1061
- record_access?: string;
1062
- placeholder?: {
1063
- key: string;
1064
- operator: TicketConditionOperator;
1065
- value: any;
1066
- }[];
1067
- response?: TicketConditionRow[];
1068
- error?: TicketConditionRow[];
1100
+ /**
1101
+ * Rows on the answer of the action whose Then chain this Condition is in, whatever its shape: a key is
1102
+ * a path in the answer ("record_id" on a posted record, "body[status]" or "headers[content-type]" on a
1103
+ * response), "" the whole answer as text. A row that does not pass fails the chain here with
1104
+ * CONDITION_FAILED. Inside a Then chain only; answers nothing.
1105
+ */
1106
+ response: TicketConditionRow[];
1069
1107
  };
1070
1108
  err?: TicketAction[];
1071
1109
  };
1072
- /** The Check of an action: rows on its answer (TicketConditionRow, keys paths in the answer; "" is the whole answer as text). */
1073
- type TicketAnswerCondition = {
1074
- data?: TicketConditionRow[];
1075
- };
1076
1110
  /** What a consumption answers when no Respond action composes the answer. */
1077
1111
  type TicketReceipt = {
1078
1112
  ticket_id: string;
@@ -1111,6 +1145,15 @@ type Ticket = {
1111
1145
  * https://docs.skapi.com/deprecated/deprecated.html#tickets-saved-before-this-release
1112
1146
  */
1113
1147
  legacy?: boolean;
1148
+ /**
1149
+ * The rules the ticket was saved under. 2: an HTTP request's answer is the whole response
1150
+ * ({ status, headers, body }). Absent on a ticket saved before 2026-10-09: its req actions
1151
+ * keep answering the body alone, as it was written to read them, until it is registered
1152
+ * again (the dashboard moves such references under [body] when the ticket is opened).
1153
+ * Returned to the project owner. See
1154
+ * https://docs.skapi.com/deprecated/deprecated.html#a-request-s-answer-was-its-body
1155
+ */
1156
+ rules_version?: number;
1114
1157
  };
1115
1158
  type TicketErrorCode = 'INVALID_SERVICE' | 'SERVICE_DISABLED' | 'TICKET_NOT_FOUND' | 'TICKET_EXPIRED' | 'TICKET_EXHAUSTED' | 'USER_LIMIT_REACHED' | 'ISSUER_CANNOT_CONSUME' | 'AUTH_REQUIRED' | 'METHOD_NOT_ALLOWED' | 'CONDITION_FAILED' | 'PATH_NOT_FOUND' | 'PLACEHOLDER_MISSING' | 'REQUEST_FAILED' | 'TIMEOUT' | 'ACTION_FAILED' | 'ACTION_FORBIDDEN' | 'QUOTA_EXCEEDED' | 'ALREADY_RESPONDED' | 'INTERNAL_ERROR';
1116
1159
  /**
@@ -1176,7 +1219,6 @@ type Types_Table = Table;
1176
1219
  type Types_Tag = Tag;
1177
1220
  type Types_Ticket = Ticket;
1178
1221
  type Types_TicketAction = TicketAction;
1179
- type Types_TicketAnswerCondition = TicketAnswerCondition;
1180
1222
  type Types_TicketCondition = TicketCondition;
1181
1223
  type Types_TicketConditionOperator = TicketConditionOperator;
1182
1224
  type Types_TicketConditionRow = TicketConditionRow;
@@ -1191,7 +1233,7 @@ type Types_UserProfile = UserProfile;
1191
1233
  type Types_UserPublic = UserPublic;
1192
1234
  type Types_WebSocketMessage = WebSocketMessage;
1193
1235
  declare namespace Types {
1194
- export type { Types_BinaryFile as BinaryFile, Types_Condition as Condition, Types_Connection as Connection, Types_ConnectionInfo as ConnectionInfo, Types_DatabaseResponse as DatabaseResponse, Types_DelRecordQuery as DelRecordQuery, Types_EncryptionOptions as EncryptionOptions, Types_FetchOptions as FetchOptions, Types_FileInfo as FileInfo, Types_Form as Form, Types_GetRecordQuery as GetRecordQuery, Types_Index as Index, Types_Newsletter as Newsletter, Types_NewsletterGroup as NewsletterGroup, Types_PostRecordConfig as PostRecordConfig, Types_ProgressCallback as ProgressCallback, Types_RTCConnector as RTCConnector, Types_RTCConnectorParams as RTCConnectorParams, Types_RTCEvent as RTCEvent, Types_RTCReceiverParams as RTCReceiverParams, Types_RTCResolved as RTCResolved, Types_RealtimeCallback as RealtimeCallback, Types_RecordData as RecordData, Types_RecordEncryptionInfo as RecordEncryptionInfo, Types_RequestHistory as RequestHistory, Types_Subscription as Subscription, Types_Table as Table, Types_Tag as Tag, Types_Ticket as Ticket, Types_TicketAction as TicketAction, Types_TicketAnswerCondition as TicketAnswerCondition, Types_TicketCondition as TicketCondition, Types_TicketConditionOperator as TicketConditionOperator, Types_TicketConditionRow as TicketConditionRow, Types_TicketError as TicketError, Types_TicketErrorCode as TicketErrorCode, Types_TicketReceipt as TicketReceipt, Types_TicketResponseCondition as TicketResponseCondition, Types_TicketSignatureCondition as TicketSignatureCondition, Types_UniqueId as UniqueId, Types_UserAttributes as UserAttributes, Types_UserProfile as UserProfile, Types_UserPublic as UserPublic, Types_WebSocketMessage as WebSocketMessage };
1236
+ export type { Types_BinaryFile as BinaryFile, Types_Condition as Condition, Types_Connection as Connection, Types_ConnectionInfo as ConnectionInfo, Types_DatabaseResponse as DatabaseResponse, Types_DelRecordQuery as DelRecordQuery, Types_EncryptionOptions as EncryptionOptions, Types_FetchOptions as FetchOptions, Types_FileInfo as FileInfo, Types_Form as Form, Types_GetRecordQuery as GetRecordQuery, Types_Index as Index, Types_Newsletter as Newsletter, Types_NewsletterGroup as NewsletterGroup, Types_PostRecordConfig as PostRecordConfig, Types_ProgressCallback as ProgressCallback, Types_RTCConnector as RTCConnector, Types_RTCConnectorParams as RTCConnectorParams, Types_RTCEvent as RTCEvent, Types_RTCReceiverParams as RTCReceiverParams, Types_RTCResolved as RTCResolved, Types_RealtimeCallback as RealtimeCallback, Types_RecordData as RecordData, Types_RecordEncryptionInfo as RecordEncryptionInfo, Types_RequestHistory as RequestHistory, Types_Subscription as Subscription, Types_Table as Table, Types_Tag as Tag, Types_Ticket as Ticket, Types_TicketAction as TicketAction, Types_TicketCondition as TicketCondition, Types_TicketConditionOperator as TicketConditionOperator, Types_TicketConditionRow as TicketConditionRow, Types_TicketError as TicketError, Types_TicketErrorCode as TicketErrorCode, Types_TicketReceipt as TicketReceipt, Types_TicketResponseCondition as TicketResponseCondition, Types_TicketSignatureCondition as TicketSignatureCondition, Types_UniqueId as UniqueId, Types_UserAttributes as UserAttributes, Types_UserProfile as UserProfile, Types_UserPublic as UserPublic, Types_WebSocketMessage as WebSocketMessage };
1195
1237
  }
1196
1238
 
1197
1239
  declare function terminatePendingRequests(): void;
@@ -3114,4 +3156,4 @@ declare class SkapiError extends Error {
3114
3156
  });
3115
3157
  }
3116
3158
 
3117
- export { type BinaryFile, type Condition, type Connection, type ConnectionInfo, type DatabaseResponse, type DelRecordQuery, type FetchOptions, type FileInfo, type Form, type GetRecordQuery, type Index, type Newsletter, type NewsletterGroup, type PostRecordConfig, type ProgressCallback, type RTCConnector, type RTCConnectorParams, type RTCEvent, type RTCReceiverParams, type RTCResolved, type RealtimeCallback, type RecordData, Skapi, SkapiError, type Subscription, type Table, type Tag, type Ticket, type TicketAction, type TicketAnswerCondition, type TicketCondition, type TicketConditionOperator, type TicketConditionRow, type TicketError, type TicketErrorCode, type TicketReceipt, type TicketResponseCondition, type TicketSignatureCondition, Types, type UniqueId, type UserAttributes, type UserProfile, type UserPublic, type WebSocketMessage };
3159
+ export { type BinaryFile, type Condition, type Connection, type ConnectionInfo, type DatabaseResponse, type DelRecordQuery, type FetchOptions, type FileInfo, type Form, type GetRecordQuery, type Index, type Newsletter, type NewsletterGroup, type PostRecordConfig, type ProgressCallback, type RTCConnector, type RTCConnectorParams, type RTCEvent, type RTCReceiverParams, type RTCResolved, type RealtimeCallback, type RecordData, Skapi, SkapiError, type Subscription, type Table, type Tag, type Ticket, type TicketAction, type TicketCondition, type TicketConditionOperator, type TicketConditionRow, type TicketError, type TicketErrorCode, type TicketReceipt, type TicketResponseCondition, type TicketSignatureCondition, Types, type UniqueId, type UserAttributes, type UserProfile, type UserPublic, type WebSocketMessage };
package/dist/skapi.d.ts CHANGED
@@ -296,6 +296,13 @@ type Newsletter = {
296
296
  * A number for the 0 ~ 99 groups, the group name for a named newsletter group.
297
297
  */
298
298
  group: number | string;
299
+ /**
300
+ * true: mailed to the group's dry address, so it is stored and was sent to nobody. The
301
+ * Newsletters page's Send button, or a ticket's Send newsletter action, sends it later.
302
+ */
303
+ dry?: boolean;
304
+ /** When the Send button or a ticket's Send newsletter action sent it, in ms. Absent on a newsletter that went out by e-mail. */
305
+ sent?: number;
299
306
  };
300
307
  type NewsletterGroup = {
301
308
  /** Name of the newsletter group. */
@@ -716,7 +723,7 @@ type TicketConditionRow = {
716
723
  * Where the row looks, relative to its own list and written without `${ }`:
717
724
  * - `data` rows: a path into the request body. "id" is the body's `id`, "order[id]" is `order.id`.
718
725
  * - `params` rows: a path into the query string, read the same way.
719
- * - `data` rows of a req action's response condition: a path into the response body ("status" is the response's `status`).
726
+ * - `response` rows of a cond action: a path into the enclosing action's answer ("body[status]" is a response's body.status, "record_id" a posted record's id); "" is the whole answer as text.
720
727
  * - `headers` rows: the header name, matched case-insensitively.
721
728
  * - `user` rows: the consumer attribute name.
722
729
  *
@@ -838,11 +845,10 @@ type TicketCondition = {
838
845
  record_access?: string;
839
846
  };
840
847
  /**
841
- * What a `req` action checks on the response before its nested actions run: `headers` and
842
- * `data` rows work as in the ticket's condition (captures and `setValueWhenMatch` included).
843
- * `headers` rows read the response headers and `data` row keys are paths into the parsed
844
- * response body. `user` and `record_access` still check the consumer, so they only work for
845
- * signed requests. A response that is not 2xx fails before this is checked.
848
+ * Skapi's own billing rows only (the super master registers them): the response check a `req`
849
+ * carried before 2026-10-09. Anyone else checks a response with a cond action in the req's
850
+ * Then chain. `headers` rows read the response headers and `data` row keys are paths into the
851
+ * parsed body; `user` and `record_access` check the consumer.
846
852
  */
847
853
  type TicketResponseCondition = Pick<TicketCondition, 'headers' | 'data' | 'user' | 'record_access'>;
848
854
  /**
@@ -864,7 +870,7 @@ type TicketResponseCondition = Pick<TicketCondition, 'headers' | 'data' | 'user'
864
870
  * | `${user}`, `${user[key]}` | The signed-in user's attributes. Signed requests only. |
865
871
  * | `${ip}`, `${user_agent}`, `${method}` | The caller's IP address, User-Agent and HTTP method. |
866
872
  * | `${record_access}` | The record ID the condition's `record_access` names. Signed requests only. |
867
- * | `${response}`, `${response[key]}` | The answer of the enclosing action, in its Then chain (`actions`) and the `err` chains inside it: the record a pstr posted, the parsed body of a req's response, the SUCCESS text of acsg and acsr. |
873
+ * | `${response}`, `${response[key]}` | The answer of the enclosing action, in its Then chain (`actions`) and the `err` chains inside it: the record a pstr posted, the response of a req ({ status, headers, body }), the SUCCESS text of acsg, acsr, mail and nlsd. |
868
874
  * | `${error}`, `${error[key]}` | In an `err` chain, the failure: `code`, `message`, `detail`, `action` (the act) and `path`. |
869
875
  * | `${ticket}`, `${ticket[key]}` | This consumption: `id`, `service`, `owner`, `consume_id`, `timestamp` and `hash`. |
870
876
  * | `${CLIENT_SECRET}` | Reserved. See `secretName` on the req action. |
@@ -872,18 +878,19 @@ type TicketResponseCondition = Pick<TicketCondition, 'headers' | 'data' | 'user'
872
878
  * Registration refuses anything else inside `${ }` (an unknown root such as `${id}`, keys under
873
879
  * a root that takes none such as `${ip[x]}`, `${placeholder}` or `${headers}` without a key,
874
880
  * broken brackets) with a message listing these forms, `${result}` (gone: an answer is read as
875
- * `${response}` in the action's Then chain, or captured by its Check), and a reference written
881
+ * `${response}` in the action's Then chain, or captured there by a Condition action), and a reference written
876
882
  * where it can never resolve (`${response}` outside a Then chain, `${error}` outside an `err`
877
883
  * chain, `${record_access}` when the condition names no record). When the action runs, a
878
884
  * reference that does not resolve fails it before it does anything: PATH_NOT_FOUND,
879
885
  * PLACEHOLDER_MISSING for a placeholder that was never captured, or AUTH_REQUIRED for `${user}`
880
886
  * on a request that is not signed in. Its `err` chain runs and the consumption stops.
881
887
  *
882
- * Every action but resp and cond answers something (the record, the response body, a SUCCESS
883
- * text) and may carry a Check (`condition`: rows on that answer, a key "" the whole text; a miss
884
- * fails the action) and a Then chain (`actions`, reading the answer as `${response}`). `retry:
885
- * true` on acsg, acsr, pstr and req tries a failure again, up to 3 more times, 1, 2 and 4
886
- * seconds apart, while the time budget holds them; never for a failure inside Then.
888
+ * Every action but resp and cond answers something (the record, the response as { status, headers, body }, a SUCCESS
889
+ * text) and may carry a Then chain (`actions`, reading the answer as `${response}`). A Condition
890
+ * action in that chain checks the answer: its `response` rows read it whole (key "") or by key,
891
+ * whatever its shape. `retry: true` on acsg, acsr, pstr, req, mail and nlsd tries a failure again,
892
+ * up to 3 more times, 1, 2 and 4 seconds apart, while the time budget holds them; never for a
893
+ * failure inside Then.
887
894
  */
888
895
  type TicketAction = {
889
896
  /** Set the access group of a user. Answers the SUCCESS text the grant returns. */
@@ -893,8 +900,6 @@ type TicketAction = {
893
900
  group: number | 'admin' | `${string}\${${string}}${string}`;
894
901
  /** Blank = the consumer (signed-in consumption only). The project owner cannot be a target. */
895
902
  user_id?: string;
896
- /** The Check: rows on the answer. */
897
- condition?: TicketAnswerCondition;
898
903
  /** The Then chain, reading the answer as `${response}`. */
899
904
  actions?: TicketAction[];
900
905
  };
@@ -908,7 +913,6 @@ type TicketAction = {
908
913
  record_id: string;
909
914
  /** Blank = the consumer. */
910
915
  user_id?: string | string[];
911
- condition?: TicketAnswerCondition;
912
916
  actions?: TicketAction[];
913
917
  };
914
918
  err?: TicketAction[];
@@ -936,15 +940,13 @@ type TicketAction = {
936
940
  source?: PostRecordConfig['source'];
937
941
  /** Post as this user instead of the project owner. */
938
942
  user_id?: string;
939
- /** The Check: rows on the record posted, such as `record_id`. */
940
- condition?: TicketAnswerCondition;
941
943
  /** The Then chain, reading the record as `${response}` (`${response[record_id]}`). */
942
944
  actions?: TicketAction[];
943
945
  };
944
946
  err?: TicketAction[];
945
947
  retry?: boolean;
946
948
  } | {
947
- /** HTTP request with its own response condition and nested chain. Answers the parsed response body. */
949
+ /** HTTP request with a nested chain on its response. Answers the whole response: { status, headers, body }. */
948
950
  act: 'req';
949
951
  exe: {
950
952
  /**
@@ -1009,13 +1011,56 @@ type TicketAction = {
1009
1011
  };
1010
1012
  /** Legacy. Registration moves these rows to the end of `condition.data`. */
1011
1013
  match?: TicketConditionRow[];
1012
- /** Checked against the response. Captures land in the shared placeholder pool. See TicketResponseCondition. */
1014
+ /** Skapi's own billing rows only. A response check is a Condition action in `actions`, whose `response` rows read the answer. */
1013
1015
  condition?: TicketResponseCondition;
1014
1016
  /**
1015
- * Nested chain, run when the response passes `condition`. It reads the response body
1016
- * as `${response}` and `${response[key]}`, while `${data}` is still the incoming
1017
- * request body. Any action can nest, including another req with its own `secretName`.
1017
+ * Nested chain, run on an answer below 300. It reads the response as `${response}`:
1018
+ * `${response[status]}`, `${response[headers][content-type]}` (header names in
1019
+ * lowercase) and `${response[body][key]}`, while `${data}` is still the incoming
1020
+ * request body. A cond in it checks the response. Any action can nest, including
1021
+ * another req with its own `secretName`.
1022
+ */
1023
+ actions?: TicketAction[];
1024
+ };
1025
+ err?: TicketAction[];
1026
+ retry?: boolean;
1027
+ } | {
1028
+ /**
1029
+ * Send e-mail: one e-mail from a CUSTOM template of the project (the Custom tab of the
1030
+ * Automated Emails page) to one address, from the project's alias. Counts as one e-mail
1031
+ * send (the plan's monthly sends, the Free owner cap and the complaint shutoff apply; a
1032
+ * refusal is QUOTA_EXCEEDED). Answers "SUCCESS: E-mail sent to <address>."
1033
+ */
1034
+ act: 'mail';
1035
+ exe: {
1036
+ /** The template's ID, as the Custom tab and the upload reply show it. Literal; it must be stored when the ticket is registered. */
1037
+ template: string;
1038
+ /** The recipient: one address, or a reference that gives one, such as "${user[email]}" or "${data[email]}". */
1039
+ to: string;
1040
+ /**
1041
+ * Values for the placeholders the template carries, by name: { "order": "${data[order][id]}" } fills
1042
+ * ${order}. Templated. "service_name" and "email" (the recipient) are filled by default and may be
1043
+ * overwritten here. Up to 30.
1018
1044
  */
1045
+ placeholders?: {
1046
+ [name: string]: string | number | boolean;
1047
+ };
1048
+ actions?: TicketAction[];
1049
+ };
1050
+ err?: TicketAction[];
1051
+ retry?: boolean;
1052
+ } | {
1053
+ /**
1054
+ * Send newsletter: a stored newsletter of a group, dry or already sent, to every subscriber of the
1055
+ * group, the way an e-mailed newsletter goes out (one e-mail send per subscriber, same gates).
1056
+ * Answers "SUCCESS: Newsletter sent to the subscribers of <group>."
1057
+ */
1058
+ act: 'nlsd';
1059
+ exe: {
1060
+ /** "public", "authorized", a number from 2 to 99, or a named group. Literal. */
1061
+ group: 'public' | 'authorized' | number | string;
1062
+ /** The newsletter's message_id (getNewsletters()). Literal; it must be stored under the group when the ticket is registered. */
1063
+ newsletter: string;
1019
1064
  actions?: TicketAction[];
1020
1065
  };
1021
1066
  err?: TicketAction[];
@@ -1052,27 +1097,16 @@ type TicketAction = {
1052
1097
  */
1053
1098
  act: 'cond';
1054
1099
  exe: {
1055
- data?: TicketConditionRow[];
1056
- params?: TicketConditionRow[];
1057
- headers?: TicketCondition['headers'];
1058
- ip?: TicketCondition['ip'];
1059
- user_agent?: TicketCondition['user_agent'];
1060
- user?: TicketCondition['user'];
1061
- record_access?: string;
1062
- placeholder?: {
1063
- key: string;
1064
- operator: TicketConditionOperator;
1065
- value: any;
1066
- }[];
1067
- response?: TicketConditionRow[];
1068
- error?: TicketConditionRow[];
1100
+ /**
1101
+ * Rows on the answer of the action whose Then chain this Condition is in, whatever its shape: a key is
1102
+ * a path in the answer ("record_id" on a posted record, "body[status]" or "headers[content-type]" on a
1103
+ * response), "" the whole answer as text. A row that does not pass fails the chain here with
1104
+ * CONDITION_FAILED. Inside a Then chain only; answers nothing.
1105
+ */
1106
+ response: TicketConditionRow[];
1069
1107
  };
1070
1108
  err?: TicketAction[];
1071
1109
  };
1072
- /** The Check of an action: rows on its answer (TicketConditionRow, keys paths in the answer; "" is the whole answer as text). */
1073
- type TicketAnswerCondition = {
1074
- data?: TicketConditionRow[];
1075
- };
1076
1110
  /** What a consumption answers when no Respond action composes the answer. */
1077
1111
  type TicketReceipt = {
1078
1112
  ticket_id: string;
@@ -1111,6 +1145,15 @@ type Ticket = {
1111
1145
  * https://docs.skapi.com/deprecated/deprecated.html#tickets-saved-before-this-release
1112
1146
  */
1113
1147
  legacy?: boolean;
1148
+ /**
1149
+ * The rules the ticket was saved under. 2: an HTTP request's answer is the whole response
1150
+ * ({ status, headers, body }). Absent on a ticket saved before 2026-10-09: its req actions
1151
+ * keep answering the body alone, as it was written to read them, until it is registered
1152
+ * again (the dashboard moves such references under [body] when the ticket is opened).
1153
+ * Returned to the project owner. See
1154
+ * https://docs.skapi.com/deprecated/deprecated.html#a-request-s-answer-was-its-body
1155
+ */
1156
+ rules_version?: number;
1114
1157
  };
1115
1158
  type TicketErrorCode = 'INVALID_SERVICE' | 'SERVICE_DISABLED' | 'TICKET_NOT_FOUND' | 'TICKET_EXPIRED' | 'TICKET_EXHAUSTED' | 'USER_LIMIT_REACHED' | 'ISSUER_CANNOT_CONSUME' | 'AUTH_REQUIRED' | 'METHOD_NOT_ALLOWED' | 'CONDITION_FAILED' | 'PATH_NOT_FOUND' | 'PLACEHOLDER_MISSING' | 'REQUEST_FAILED' | 'TIMEOUT' | 'ACTION_FAILED' | 'ACTION_FORBIDDEN' | 'QUOTA_EXCEEDED' | 'ALREADY_RESPONDED' | 'INTERNAL_ERROR';
1116
1159
  /**
@@ -1176,7 +1219,6 @@ type Types_Table = Table;
1176
1219
  type Types_Tag = Tag;
1177
1220
  type Types_Ticket = Ticket;
1178
1221
  type Types_TicketAction = TicketAction;
1179
- type Types_TicketAnswerCondition = TicketAnswerCondition;
1180
1222
  type Types_TicketCondition = TicketCondition;
1181
1223
  type Types_TicketConditionOperator = TicketConditionOperator;
1182
1224
  type Types_TicketConditionRow = TicketConditionRow;
@@ -1191,7 +1233,7 @@ type Types_UserProfile = UserProfile;
1191
1233
  type Types_UserPublic = UserPublic;
1192
1234
  type Types_WebSocketMessage = WebSocketMessage;
1193
1235
  declare namespace Types {
1194
- export type { Types_BinaryFile as BinaryFile, Types_Condition as Condition, Types_Connection as Connection, Types_ConnectionInfo as ConnectionInfo, Types_DatabaseResponse as DatabaseResponse, Types_DelRecordQuery as DelRecordQuery, Types_EncryptionOptions as EncryptionOptions, Types_FetchOptions as FetchOptions, Types_FileInfo as FileInfo, Types_Form as Form, Types_GetRecordQuery as GetRecordQuery, Types_Index as Index, Types_Newsletter as Newsletter, Types_NewsletterGroup as NewsletterGroup, Types_PostRecordConfig as PostRecordConfig, Types_ProgressCallback as ProgressCallback, Types_RTCConnector as RTCConnector, Types_RTCConnectorParams as RTCConnectorParams, Types_RTCEvent as RTCEvent, Types_RTCReceiverParams as RTCReceiverParams, Types_RTCResolved as RTCResolved, Types_RealtimeCallback as RealtimeCallback, Types_RecordData as RecordData, Types_RecordEncryptionInfo as RecordEncryptionInfo, Types_RequestHistory as RequestHistory, Types_Subscription as Subscription, Types_Table as Table, Types_Tag as Tag, Types_Ticket as Ticket, Types_TicketAction as TicketAction, Types_TicketAnswerCondition as TicketAnswerCondition, Types_TicketCondition as TicketCondition, Types_TicketConditionOperator as TicketConditionOperator, Types_TicketConditionRow as TicketConditionRow, Types_TicketError as TicketError, Types_TicketErrorCode as TicketErrorCode, Types_TicketReceipt as TicketReceipt, Types_TicketResponseCondition as TicketResponseCondition, Types_TicketSignatureCondition as TicketSignatureCondition, Types_UniqueId as UniqueId, Types_UserAttributes as UserAttributes, Types_UserProfile as UserProfile, Types_UserPublic as UserPublic, Types_WebSocketMessage as WebSocketMessage };
1236
+ export type { Types_BinaryFile as BinaryFile, Types_Condition as Condition, Types_Connection as Connection, Types_ConnectionInfo as ConnectionInfo, Types_DatabaseResponse as DatabaseResponse, Types_DelRecordQuery as DelRecordQuery, Types_EncryptionOptions as EncryptionOptions, Types_FetchOptions as FetchOptions, Types_FileInfo as FileInfo, Types_Form as Form, Types_GetRecordQuery as GetRecordQuery, Types_Index as Index, Types_Newsletter as Newsletter, Types_NewsletterGroup as NewsletterGroup, Types_PostRecordConfig as PostRecordConfig, Types_ProgressCallback as ProgressCallback, Types_RTCConnector as RTCConnector, Types_RTCConnectorParams as RTCConnectorParams, Types_RTCEvent as RTCEvent, Types_RTCReceiverParams as RTCReceiverParams, Types_RTCResolved as RTCResolved, Types_RealtimeCallback as RealtimeCallback, Types_RecordData as RecordData, Types_RecordEncryptionInfo as RecordEncryptionInfo, Types_RequestHistory as RequestHistory, Types_Subscription as Subscription, Types_Table as Table, Types_Tag as Tag, Types_Ticket as Ticket, Types_TicketAction as TicketAction, Types_TicketCondition as TicketCondition, Types_TicketConditionOperator as TicketConditionOperator, Types_TicketConditionRow as TicketConditionRow, Types_TicketError as TicketError, Types_TicketErrorCode as TicketErrorCode, Types_TicketReceipt as TicketReceipt, Types_TicketResponseCondition as TicketResponseCondition, Types_TicketSignatureCondition as TicketSignatureCondition, Types_UniqueId as UniqueId, Types_UserAttributes as UserAttributes, Types_UserProfile as UserProfile, Types_UserPublic as UserPublic, Types_WebSocketMessage as WebSocketMessage };
1195
1237
  }
1196
1238
 
1197
1239
  declare function terminatePendingRequests(): void;
@@ -3114,4 +3156,4 @@ declare class SkapiError extends Error {
3114
3156
  });
3115
3157
  }
3116
3158
 
3117
- export { type BinaryFile, type Condition, type Connection, type ConnectionInfo, type DatabaseResponse, type DelRecordQuery, type FetchOptions, type FileInfo, type Form, type GetRecordQuery, type Index, type Newsletter, type NewsletterGroup, type PostRecordConfig, type ProgressCallback, type RTCConnector, type RTCConnectorParams, type RTCEvent, type RTCReceiverParams, type RTCResolved, type RealtimeCallback, type RecordData, Skapi, SkapiError, type Subscription, type Table, type Tag, type Ticket, type TicketAction, type TicketAnswerCondition, type TicketCondition, type TicketConditionOperator, type TicketConditionRow, type TicketError, type TicketErrorCode, type TicketReceipt, type TicketResponseCondition, type TicketSignatureCondition, Types, type UniqueId, type UserAttributes, type UserProfile, type UserPublic, type WebSocketMessage };
3159
+ export { type BinaryFile, type Condition, type Connection, type ConnectionInfo, type DatabaseResponse, type DelRecordQuery, type FetchOptions, type FileInfo, type Form, type GetRecordQuery, type Index, type Newsletter, type NewsletterGroup, type PostRecordConfig, type ProgressCallback, type RTCConnector, type RTCConnectorParams, type RTCEvent, type RTCReceiverParams, type RTCResolved, type RealtimeCallback, type RecordData, Skapi, SkapiError, type Subscription, type Table, type Tag, type Ticket, type TicketAction, type TicketCondition, type TicketConditionOperator, type TicketConditionRow, type TicketError, type TicketErrorCode, type TicketReceipt, type TicketResponseCondition, type TicketSignatureCondition, Types, type UniqueId, type UserAttributes, type UserProfile, type UserPublic, type WebSocketMessage };