raims 0.1.3__tar.gz
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.
- raims-0.1.3/.gitignore +26 -0
- raims-0.1.3/CONTRIBUTING.md +27 -0
- raims-0.1.3/LICENSE +21 -0
- raims-0.1.3/PKG-INFO +157 -0
- raims-0.1.3/README.md +134 -0
- raims-0.1.3/SECURITY.md +15 -0
- raims-0.1.3/contracts/openapi.json +24000 -0
- raims-0.1.3/contracts/python-api.json +19969 -0
- raims-0.1.3/contracts/service-map.json +98 -0
- raims-0.1.3/contracts/source.json +10 -0
- raims-0.1.3/docs/errors-and-retries.md +69 -0
- raims-0.1.3/docs/pagination.md +41 -0
- raims-0.1.3/docs/reference.en.json +192 -0
- raims-0.1.3/docs/reference.md +687 -0
- raims-0.1.3/docs/usage.md +144 -0
- raims-0.1.3/docs/webhooks.md +49 -0
- raims-0.1.3/pyproject.toml +48 -0
- raims-0.1.3/scripts/check-compatibility.py +309 -0
- raims-0.1.3/scripts/check.py +20 -0
- raims-0.1.3/scripts/generate.py +569 -0
- raims-0.1.3/scripts/publish-requirements.txt +405 -0
- raims-0.1.3/scripts/release.py +468 -0
- raims-0.1.3/src/raims/__init__.py +67 -0
- raims-0.1.3/src/raims/_client.py +560 -0
- raims-0.1.3/src/raims/_errors.py +80 -0
- raims-0.1.3/src/raims/_generated/contract.json +6982 -0
- raims-0.1.3/src/raims/_options.py +65 -0
- raims-0.1.3/src/raims/_pagination.py +137 -0
- raims-0.1.3/src/raims/_resource.py +66 -0
- raims-0.1.3/src/raims/_response.py +29 -0
- raims-0.1.3/src/raims/_validation.py +197 -0
- raims-0.1.3/src/raims/_version.py +1 -0
- raims-0.1.3/src/raims/_webhook.py +111 -0
- raims-0.1.3/src/raims/enum_values.py +207 -0
- raims-0.1.3/src/raims/models.py +1791 -0
- raims-0.1.3/src/raims/py.typed +0 -0
- raims-0.1.3/src/raims/services.py +666 -0
- raims-0.1.3/src/raims/types.py +435 -0
raims-0.1.3/.gitignore
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
*.egg-info/
|
|
4
|
+
.venv/
|
|
5
|
+
venv/
|
|
6
|
+
build/
|
|
7
|
+
dist/
|
|
8
|
+
.mypy_cache/
|
|
9
|
+
.ruff_cache/
|
|
10
|
+
.pytest_cache/
|
|
11
|
+
.coverage
|
|
12
|
+
.env
|
|
13
|
+
|
|
14
|
+
# Internal planning is not part of public source.
|
|
15
|
+
[Tt][Oo][Dd][Oo]
|
|
16
|
+
[Tt][Oo][Dd][Oo][._-]*
|
|
17
|
+
[Bb][Aa][Cc][Kk][Ll][Oo][Gg]
|
|
18
|
+
[Bb][Aa][Cc][Kk][Ll][Oo][Gg][._-]*
|
|
19
|
+
[Rr][Oo][Aa][Dd][Mm][Aa][Pp]
|
|
20
|
+
[Rr][Oo][Aa][Dd][Mm][Aa][Pp][._-]*
|
|
21
|
+
|
|
22
|
+
# Local project instructions and maintenance files.
|
|
23
|
+
[Aa][Gg][Ee][Nn][Tt][Ss].[Mm][Dd]
|
|
24
|
+
/[Dd][Oo][Cc][Ss]/[Mm][Aa][Ii][Nn][Tt][Ee][Nn][Aa][Nn][Cc][Ee].[Mm][Dd]
|
|
25
|
+
/[Ss][Ee][Cc][Uu][Rr][Ii][Tt][Yy]/[Rr][Ee][Aa][Dd][Mm][Ee].[Mm][Dd]
|
|
26
|
+
/[Tt][Ee][Mm][Pp][Ll][Aa][Tt][Ee][Ss]/[Cc][Ii]/
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Report bugs through this repository's GitHub issues. Include:
|
|
4
|
+
|
|
5
|
+
- The SDK version or source commit.
|
|
6
|
+
- The runtime version and operating system.
|
|
7
|
+
- Expected and actual behavior.
|
|
8
|
+
- A minimal reproduction using synthetic data.
|
|
9
|
+
|
|
10
|
+
Report vulnerabilities privately as described in [SECURITY.md](SECURITY.md).
|
|
11
|
+
Keep API keys, webhook secrets, customer data, and URLs that grant access to
|
|
12
|
+
resources out of public reports and examples.
|
|
13
|
+
|
|
14
|
+
## Working with the source
|
|
15
|
+
|
|
16
|
+
Use Python 3.10 or later and install the SDK dependencies as described in the README.
|
|
17
|
+
|
|
18
|
+
From the SDK root:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
python scripts/generate.py --check
|
|
22
|
+
python scripts/check-compatibility.py
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Keep changes focused and preserve public API compatibility. Regenerate
|
|
26
|
+
contract-derived files instead of editing them by hand. Preserve license
|
|
27
|
+
notices and attribution in contributions.
|
raims-0.1.3/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Raims
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
raims-0.1.3/PKG-INFO
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: raims
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: Official Python SDK for the Raims public API.
|
|
5
|
+
Project-URL: Documentation, https://docs.raims.com/en/integracoes/sdk-python
|
|
6
|
+
Project-URL: Repository, https://github.com/raimshq/raims-python
|
|
7
|
+
Project-URL: Issues, https://github.com/raimshq/raims-python/issues
|
|
8
|
+
Author: Raims
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: payments,pix,raims,sdk
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Typing :: Typed
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Requires-Dist: httpx<0.29,>=0.28.1
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# Raims Python
|
|
25
|
+
|
|
26
|
+
Official Python SDK for the Raims public API.
|
|
27
|
+
|
|
28
|
+
Use the SDK in server applications, with synchronous and asynchronous clients,
|
|
29
|
+
typed parameters, read-only responses, cursor pagination, and webhook signature
|
|
30
|
+
verification.
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
Requires Python 3.10 or later. In your application's virtual environment:
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
python -m pip install raims
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The package and import name are both `raims`. It uses HTTPX for HTTP transport.
|
|
41
|
+
|
|
42
|
+
To update to the current stable version:
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
python -m pip install --upgrade raims
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Read the [release notes](https://github.com/raimshq/raims-python/releases) and
|
|
49
|
+
test your integration after updating. Pin the SDK and its dependencies in your
|
|
50
|
+
application's dependency configuration to reproduce installations.
|
|
51
|
+
Future updates are not applied automatically.
|
|
52
|
+
|
|
53
|
+
[GitHub releases](https://github.com/raimshq/raims-python/releases/latest) also
|
|
54
|
+
provide wheel and source archives. Verify the downloaded file with `SHA256SUMS`
|
|
55
|
+
before installing it. Install the downloaded wheel in your application environment:
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
python -m pip install /path/to/downloaded-package.whl
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## First request
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
import os
|
|
65
|
+
|
|
66
|
+
from raims import RaimsClient
|
|
67
|
+
|
|
68
|
+
with RaimsClient(os.environ["RAIMS_API_KEY"]) as raims:
|
|
69
|
+
page = raims.customers.list({"page_size": 20})
|
|
70
|
+
for customer in page:
|
|
71
|
+
process_customer(customer.id)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`process_customer` represents your application's processing. The base URL is
|
|
75
|
+
`https://api.raims.com` for both Sandbox and Production. The key determines the
|
|
76
|
+
company, environment, and permissions. Keep it on the server and out of version
|
|
77
|
+
control.
|
|
78
|
+
|
|
79
|
+
## Create a charge
|
|
80
|
+
|
|
81
|
+
`customer_id`, `due_date`, and `order_idempotency_key` are values your application
|
|
82
|
+
has already defined and persisted for the order. The due date uses Unix seconds
|
|
83
|
+
in UTC, and the amount uses integer cents: `15000` represents BRL 150.00.
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from raims import RequestOptions
|
|
87
|
+
|
|
88
|
+
with RaimsClient(os.environ["RAIMS_API_KEY"]) as raims:
|
|
89
|
+
charge = raims.charges.create(
|
|
90
|
+
{
|
|
91
|
+
"customer_id": customer_id,
|
|
92
|
+
"amount_cents": 15000,
|
|
93
|
+
"due_date": due_date,
|
|
94
|
+
"title": "Order 1234",
|
|
95
|
+
},
|
|
96
|
+
options=RequestOptions(idempotency_key=order_idempotency_key),
|
|
97
|
+
)
|
|
98
|
+
response = charge.last_response
|
|
99
|
+
assert response is not None
|
|
100
|
+
request_id = response.request_id
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The SDK does not generate idempotency keys or retry writes automatically.
|
|
104
|
+
If you lose a response, keep the same key and parameters and follow the
|
|
105
|
+
endpoint's rules for retrieving or retrying the operation. A `202` response
|
|
106
|
+
means processing is pending; retrieve the resource to follow its outcome.
|
|
107
|
+
|
|
108
|
+
## Asynchronous use
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
from raims import AsyncRaimsClient
|
|
112
|
+
|
|
113
|
+
async def load_customers(api_key: str) -> None:
|
|
114
|
+
async with AsyncRaimsClient(api_key) as raims:
|
|
115
|
+
page = await raims.customers.list({"page_size": 50})
|
|
116
|
+
async for customer in page.auto_paging_iter():
|
|
117
|
+
await process_customer_async(customer.id)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`process_customer_async` represents your application's asynchronous processing.
|
|
121
|
+
Normal iteration over a page accesses only the items already received.
|
|
122
|
+
`auto_paging_iter()` retrieves subsequent pages as you consume them.
|
|
123
|
+
|
|
124
|
+
## Services
|
|
125
|
+
|
|
126
|
+
| Property | Resources |
|
|
127
|
+
| --- | --- |
|
|
128
|
+
| `accounts` | Account context, number, fees, and checkout |
|
|
129
|
+
| `balances` | Balance and forecast |
|
|
130
|
+
| `customers` | Customer creation, retrieval, and deletion |
|
|
131
|
+
| `charges` | Charges, payment, documents, and refunds for a charge |
|
|
132
|
+
| `payment_links` | Payment links and email delivery requests |
|
|
133
|
+
| `refunds` | Refunds and receipts |
|
|
134
|
+
| `disputes` | Disputes |
|
|
135
|
+
| `statements` | Account statements |
|
|
136
|
+
| `withdrawals` | Withdrawals, limits, summary, and automatic settings |
|
|
137
|
+
| `withdrawal_destinations` | Withdrawal destinations |
|
|
138
|
+
| `webhooks` | Registration, health, pause, test, and secret rotation |
|
|
139
|
+
| `webhook_event_types` | Available event types |
|
|
140
|
+
| `simulations.charges` | Charge simulations with a Sandbox key |
|
|
141
|
+
| `simulations.refunds` | Refund simulations with a Sandbox key |
|
|
142
|
+
|
|
143
|
+
Services expose `create`, `retrieve`, `update`, `delete`, and `list` according
|
|
144
|
+
to the operations available. The [reference](docs/reference.md) describes each
|
|
145
|
+
method.
|
|
146
|
+
|
|
147
|
+
## Documentation
|
|
148
|
+
|
|
149
|
+
- [Configuration, responses, and documents](docs/usage.md)
|
|
150
|
+
- [Pagination](docs/pagination.md)
|
|
151
|
+
- [Errors, idempotency, and retries](docs/errors-and-retries.md)
|
|
152
|
+
- [Receiving webhooks](docs/webhooks.md)
|
|
153
|
+
- [Contributing](CONTRIBUTING.md) and [security](SECURITY.md)
|
|
154
|
+
- [Installation and integration guide](https://docs.raims.com/en/integracoes/sdk-python)
|
|
155
|
+
- [Public API](https://docs.raims.com/en/api)
|
|
156
|
+
|
|
157
|
+
Distributed under the [MIT license](LICENSE).
|
raims-0.1.3/README.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Raims Python
|
|
2
|
+
|
|
3
|
+
Official Python SDK for the Raims public API.
|
|
4
|
+
|
|
5
|
+
Use the SDK in server applications, with synchronous and asynchronous clients,
|
|
6
|
+
typed parameters, read-only responses, cursor pagination, and webhook signature
|
|
7
|
+
verification.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
Requires Python 3.10 or later. In your application's virtual environment:
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
python -m pip install raims
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The package and import name are both `raims`. It uses HTTPX for HTTP transport.
|
|
18
|
+
|
|
19
|
+
To update to the current stable version:
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
python -m pip install --upgrade raims
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Read the [release notes](https://github.com/raimshq/raims-python/releases) and
|
|
26
|
+
test your integration after updating. Pin the SDK and its dependencies in your
|
|
27
|
+
application's dependency configuration to reproduce installations.
|
|
28
|
+
Future updates are not applied automatically.
|
|
29
|
+
|
|
30
|
+
[GitHub releases](https://github.com/raimshq/raims-python/releases/latest) also
|
|
31
|
+
provide wheel and source archives. Verify the downloaded file with `SHA256SUMS`
|
|
32
|
+
before installing it. Install the downloaded wheel in your application environment:
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
python -m pip install /path/to/downloaded-package.whl
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## First request
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
import os
|
|
42
|
+
|
|
43
|
+
from raims import RaimsClient
|
|
44
|
+
|
|
45
|
+
with RaimsClient(os.environ["RAIMS_API_KEY"]) as raims:
|
|
46
|
+
page = raims.customers.list({"page_size": 20})
|
|
47
|
+
for customer in page:
|
|
48
|
+
process_customer(customer.id)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`process_customer` represents your application's processing. The base URL is
|
|
52
|
+
`https://api.raims.com` for both Sandbox and Production. The key determines the
|
|
53
|
+
company, environment, and permissions. Keep it on the server and out of version
|
|
54
|
+
control.
|
|
55
|
+
|
|
56
|
+
## Create a charge
|
|
57
|
+
|
|
58
|
+
`customer_id`, `due_date`, and `order_idempotency_key` are values your application
|
|
59
|
+
has already defined and persisted for the order. The due date uses Unix seconds
|
|
60
|
+
in UTC, and the amount uses integer cents: `15000` represents BRL 150.00.
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from raims import RequestOptions
|
|
64
|
+
|
|
65
|
+
with RaimsClient(os.environ["RAIMS_API_KEY"]) as raims:
|
|
66
|
+
charge = raims.charges.create(
|
|
67
|
+
{
|
|
68
|
+
"customer_id": customer_id,
|
|
69
|
+
"amount_cents": 15000,
|
|
70
|
+
"due_date": due_date,
|
|
71
|
+
"title": "Order 1234",
|
|
72
|
+
},
|
|
73
|
+
options=RequestOptions(idempotency_key=order_idempotency_key),
|
|
74
|
+
)
|
|
75
|
+
response = charge.last_response
|
|
76
|
+
assert response is not None
|
|
77
|
+
request_id = response.request_id
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The SDK does not generate idempotency keys or retry writes automatically.
|
|
81
|
+
If you lose a response, keep the same key and parameters and follow the
|
|
82
|
+
endpoint's rules for retrieving or retrying the operation. A `202` response
|
|
83
|
+
means processing is pending; retrieve the resource to follow its outcome.
|
|
84
|
+
|
|
85
|
+
## Asynchronous use
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from raims import AsyncRaimsClient
|
|
89
|
+
|
|
90
|
+
async def load_customers(api_key: str) -> None:
|
|
91
|
+
async with AsyncRaimsClient(api_key) as raims:
|
|
92
|
+
page = await raims.customers.list({"page_size": 50})
|
|
93
|
+
async for customer in page.auto_paging_iter():
|
|
94
|
+
await process_customer_async(customer.id)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`process_customer_async` represents your application's asynchronous processing.
|
|
98
|
+
Normal iteration over a page accesses only the items already received.
|
|
99
|
+
`auto_paging_iter()` retrieves subsequent pages as you consume them.
|
|
100
|
+
|
|
101
|
+
## Services
|
|
102
|
+
|
|
103
|
+
| Property | Resources |
|
|
104
|
+
| --- | --- |
|
|
105
|
+
| `accounts` | Account context, number, fees, and checkout |
|
|
106
|
+
| `balances` | Balance and forecast |
|
|
107
|
+
| `customers` | Customer creation, retrieval, and deletion |
|
|
108
|
+
| `charges` | Charges, payment, documents, and refunds for a charge |
|
|
109
|
+
| `payment_links` | Payment links and email delivery requests |
|
|
110
|
+
| `refunds` | Refunds and receipts |
|
|
111
|
+
| `disputes` | Disputes |
|
|
112
|
+
| `statements` | Account statements |
|
|
113
|
+
| `withdrawals` | Withdrawals, limits, summary, and automatic settings |
|
|
114
|
+
| `withdrawal_destinations` | Withdrawal destinations |
|
|
115
|
+
| `webhooks` | Registration, health, pause, test, and secret rotation |
|
|
116
|
+
| `webhook_event_types` | Available event types |
|
|
117
|
+
| `simulations.charges` | Charge simulations with a Sandbox key |
|
|
118
|
+
| `simulations.refunds` | Refund simulations with a Sandbox key |
|
|
119
|
+
|
|
120
|
+
Services expose `create`, `retrieve`, `update`, `delete`, and `list` according
|
|
121
|
+
to the operations available. The [reference](docs/reference.md) describes each
|
|
122
|
+
method.
|
|
123
|
+
|
|
124
|
+
## Documentation
|
|
125
|
+
|
|
126
|
+
- [Configuration, responses, and documents](docs/usage.md)
|
|
127
|
+
- [Pagination](docs/pagination.md)
|
|
128
|
+
- [Errors, idempotency, and retries](docs/errors-and-retries.md)
|
|
129
|
+
- [Receiving webhooks](docs/webhooks.md)
|
|
130
|
+
- [Contributing](CONTRIBUTING.md) and [security](SECURITY.md)
|
|
131
|
+
- [Installation and integration guide](https://docs.raims.com/en/integracoes/sdk-python)
|
|
132
|
+
- [Public API](https://docs.raims.com/en/api)
|
|
133
|
+
|
|
134
|
+
Distributed under the [MIT license](LICENSE).
|
raims-0.1.3/SECURITY.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Security
|
|
2
|
+
|
|
3
|
+
Report vulnerabilities privately to `security@raims.com`. Do not open a public
|
|
4
|
+
discussion containing credentials, personal data, real request or response
|
|
5
|
+
bodies, webhook secrets, or temporary URLs. Describe the behavior, affected
|
|
6
|
+
version, and a minimal reproduction using fictitious data.
|
|
7
|
+
|
|
8
|
+
The SDK is intended for the integrator's server. Store keys and secrets in a
|
|
9
|
+
vault, use the permissions your integration needs, and keep Python and its
|
|
10
|
+
dependencies updated. Check company, environment, authorization, and
|
|
11
|
+
idempotency in your application.
|
|
12
|
+
|
|
13
|
+
Webhook verification authenticates the delivery. The integrator remains
|
|
14
|
+
responsible for validating the event, deduplicating it, and persisting the work
|
|
15
|
+
before acknowledging it over HTTP.
|