Skip to content

Commit 2e57117

Browse files
feat(api): api update
1 parent 1c854af commit 2e57117

7 files changed

Lines changed: 68 additions & 100 deletions

File tree

.stats.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 21
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-d868ff00b7b07f6b6802b00f22fad531a91a76bb219a634f3f90fe488bd499ba.yml
3-
openapi_spec_hash: 20e9f2fc31feee78878cdf56e46dab60
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-78ef474b9e171a3eaa430a9dacdc2fa5c7f7d5f89147cb20573a355d3dbb9f0e.yml
3+
openapi_spec_hash: 11b6e43ef4ed724f9804c9d790a4faee
44
config_hash: 5509bb7a961ae2e79114b24c381606d4

src/cas_parser/resources/inbound_email.py

Lines changed: 31 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from __future__ import annotations
44

5-
from typing import Dict, List
5+
from typing import Dict, List, Optional
66
from typing_extensions import Literal
77

88
import httpx
@@ -73,9 +73,9 @@ def with_streaming_response(self) -> InboundEmailResourceWithStreamingResponse:
7373
def create(
7474
self,
7575
*,
76-
callback_url: str,
7776
alias: str | Omit = omit,
7877
allowed_sources: List[Literal["cdsl", "nsdl", "cams", "kfintech"]] | Omit = omit,
78+
callback_url: Optional[str] | Omit = omit,
7979
metadata: Dict[str, str] | Omit = omit,
8080
reference: str | Omit = omit,
8181
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -87,38 +87,19 @@ def create(
8787
) -> InboundEmailCreateResponse:
8888
"""
8989
Create a dedicated inbound email address for collecting CAS statements via email
90-
forwarding.
90+
forwarding. When an investor forwards a CAS email to this address, we verify the
91+
sender and make the file available to you.
9192
92-
**How it works:**
93+
`callback_url` is **optional**:
9394
94-
1. Create an inbound email with your webhook URL
95-
2. Display the email address to your user (e.g., "Forward your CAS to
96-
ie_xxx@import.casparser.in")
97-
3. When an investor forwards a CAS email, we verify the sender and deliver to
98-
your webhook
99-
100-
**Webhook Delivery:**
101-
102-
- We POST to your `callback_url` with JSON body containing files (matching
103-
EmailCASFile schema)
104-
- Failed deliveries are retried automatically with exponential backoff
105-
106-
**Inactivity:**
107-
108-
- Inbound emails with no activity in 30 days are marked inactive
109-
- Active inbound emails remain operational indefinitely
95+
- **Set it** — we POST each parsed email to your webhook as it arrives.
96+
- **Omit it** — retrieve files via `GET /v4/inbound-email/{id}/files` without
97+
building a webhook consumer.
11098
11199
Args:
112-
callback_url: Webhook URL where we POST email notifications. Must be HTTPS in production (HTTP
113-
allowed for localhost during development).
114-
115-
alias: Optional custom email prefix for user-friendly addresses.
116-
117-
- Must be 3-32 characters
118-
- Alphanumeric + hyphens only
119-
- Must start and end with letter/number
120-
- Example: `john-portfolio@import.casparser.in`
121-
- If omitted, generates random ID like `ie_abc123xyz@import.casparser.in`
100+
alias: Optional custom email prefix (e.g. `john-portfolio@import.casparser.in`). 3-32
101+
chars, alphanumeric + hyphens, must start/end with a letter or number. If
102+
omitted, a random ID is generated.
122103
123104
allowed_sources: Filter emails by CAS provider. If omitted, accepts all providers.
124105
@@ -127,6 +108,10 @@ def create(
127108
- `cams` → donotreply@camsonline.com
128109
- `kfintech` → samfS@kfintech.com
129110
111+
callback_url: Optional webhook URL where we POST parsed emails. Must be HTTPS in production
112+
(HTTP allowed for localhost). If omitted, retrieve files via
113+
`GET /v4/inbound-email/{id}/files`.
114+
130115
metadata: Optional key-value pairs (max 10) to include in webhook payload. Useful for
131116
passing context like plan_type, campaign_id, etc.
132117
@@ -145,9 +130,9 @@ def create(
145130
"/v4/inbound-email",
146131
body=maybe_transform(
147132
{
148-
"callback_url": callback_url,
149133
"alias": alias,
150134
"allowed_sources": allowed_sources,
135+
"callback_url": callback_url,
151136
"metadata": metadata,
152137
"reference": reference,
153138
},
@@ -328,9 +313,9 @@ def with_streaming_response(self) -> AsyncInboundEmailResourceWithStreamingRespo
328313
async def create(
329314
self,
330315
*,
331-
callback_url: str,
332316
alias: str | Omit = omit,
333317
allowed_sources: List[Literal["cdsl", "nsdl", "cams", "kfintech"]] | Omit = omit,
318+
callback_url: Optional[str] | Omit = omit,
334319
metadata: Dict[str, str] | Omit = omit,
335320
reference: str | Omit = omit,
336321
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -342,38 +327,19 @@ async def create(
342327
) -> InboundEmailCreateResponse:
343328
"""
344329
Create a dedicated inbound email address for collecting CAS statements via email
345-
forwarding.
330+
forwarding. When an investor forwards a CAS email to this address, we verify the
331+
sender and make the file available to you.
346332
347-
**How it works:**
333+
`callback_url` is **optional**:
348334
349-
1. Create an inbound email with your webhook URL
350-
2. Display the email address to your user (e.g., "Forward your CAS to
351-
ie_xxx@import.casparser.in")
352-
3. When an investor forwards a CAS email, we verify the sender and deliver to
353-
your webhook
354-
355-
**Webhook Delivery:**
356-
357-
- We POST to your `callback_url` with JSON body containing files (matching
358-
EmailCASFile schema)
359-
- Failed deliveries are retried automatically with exponential backoff
360-
361-
**Inactivity:**
362-
363-
- Inbound emails with no activity in 30 days are marked inactive
364-
- Active inbound emails remain operational indefinitely
335+
- **Set it** — we POST each parsed email to your webhook as it arrives.
336+
- **Omit it** — retrieve files via `GET /v4/inbound-email/{id}/files` without
337+
building a webhook consumer.
365338
366339
Args:
367-
callback_url: Webhook URL where we POST email notifications. Must be HTTPS in production (HTTP
368-
allowed for localhost during development).
369-
370-
alias: Optional custom email prefix for user-friendly addresses.
371-
372-
- Must be 3-32 characters
373-
- Alphanumeric + hyphens only
374-
- Must start and end with letter/number
375-
- Example: `john-portfolio@import.casparser.in`
376-
- If omitted, generates random ID like `ie_abc123xyz@import.casparser.in`
340+
alias: Optional custom email prefix (e.g. `john-portfolio@import.casparser.in`). 3-32
341+
chars, alphanumeric + hyphens, must start/end with a letter or number. If
342+
omitted, a random ID is generated.
377343
378344
allowed_sources: Filter emails by CAS provider. If omitted, accepts all providers.
379345
@@ -382,6 +348,10 @@ async def create(
382348
- `cams` → donotreply@camsonline.com
383349
- `kfintech` → samfS@kfintech.com
384350
351+
callback_url: Optional webhook URL where we POST parsed emails. Must be HTTPS in production
352+
(HTTP allowed for localhost). If omitted, retrieve files via
353+
`GET /v4/inbound-email/{id}/files`.
354+
385355
metadata: Optional key-value pairs (max 10) to include in webhook payload. Useful for
386356
passing context like plan_type, campaign_id, etc.
387357
@@ -400,9 +370,9 @@ async def create(
400370
"/v4/inbound-email",
401371
body=await async_maybe_transform(
402372
{
403-
"callback_url": callback_url,
404373
"alias": alias,
405374
"allowed_sources": allowed_sources,
375+
"callback_url": callback_url,
406376
"metadata": metadata,
407377
"reference": reference,
408378
},

src/cas_parser/types/inbound_email_create_params.py

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,18 @@
22

33
from __future__ import annotations
44

5-
from typing import Dict, List
6-
from typing_extensions import Literal, Required, TypedDict
5+
from typing import Dict, List, Optional
6+
from typing_extensions import Literal, TypedDict
77

88
__all__ = ["InboundEmailCreateParams"]
99

1010

1111
class InboundEmailCreateParams(TypedDict, total=False):
12-
callback_url: Required[str]
13-
"""
14-
Webhook URL where we POST email notifications. Must be HTTPS in production (HTTP
15-
allowed for localhost during development).
16-
"""
17-
1812
alias: str
19-
"""Optional custom email prefix for user-friendly addresses.
13+
"""Optional custom email prefix (e.g. `john-portfolio@import.casparser.in`).
2014
21-
- Must be 3-32 characters
22-
- Alphanumeric + hyphens only
23-
- Must start and end with letter/number
24-
- Example: `john-portfolio@import.casparser.in`
25-
- If omitted, generates random ID like `ie_abc123xyz@import.casparser.in`
15+
3-32 chars, alphanumeric + hyphens, must start/end with a letter or number. If
16+
omitted, a random ID is generated.
2617
"""
2718

2819
allowed_sources: List[Literal["cdsl", "nsdl", "cams", "kfintech"]]
@@ -34,6 +25,13 @@ class InboundEmailCreateParams(TypedDict, total=False):
3425
- `kfintech` → samfS@kfintech.com
3526
"""
3627

28+
callback_url: Optional[str]
29+
"""Optional webhook URL where we POST parsed emails.
30+
31+
Must be HTTPS in production (HTTP allowed for localhost). If omitted, retrieve
32+
files via `GET /v4/inbound-email/{id}/files`.
33+
"""
34+
3735
metadata: Dict[str, str]
3836
"""
3937
Optional key-value pairs (max 10) to include in webhook payload. Useful for

src/cas_parser/types/inbound_email_create_response.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ class InboundEmailCreateResponse(BaseModel):
1616
"""Accepted CAS providers (empty = all)"""
1717

1818
callback_url: Optional[str] = None
19-
"""Webhook URL for email notifications"""
19+
"""Webhook URL for email notifications.
20+
21+
`null` means files are only retrievable via `GET /v4/inbound-email/{id}/files`
22+
(pull delivery).
23+
"""
2024

2125
created_at: Optional[datetime] = None
2226
"""When the mailbox was created"""

src/cas_parser/types/inbound_email_list_response.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ class InboundEmail(BaseModel):
1616
"""Accepted CAS providers (empty = all)"""
1717

1818
callback_url: Optional[str] = None
19-
"""Webhook URL for email notifications"""
19+
"""Webhook URL for email notifications.
20+
21+
`null` means files are only retrievable via `GET /v4/inbound-email/{id}/files`
22+
(pull delivery).
23+
"""
2024

2125
created_at: Optional[datetime] = None
2226
"""When the mailbox was created"""

src/cas_parser/types/inbound_email_retrieve_response.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ class InboundEmailRetrieveResponse(BaseModel):
1616
"""Accepted CAS providers (empty = all)"""
1717

1818
callback_url: Optional[str] = None
19-
"""Webhook URL for email notifications"""
19+
"""Webhook URL for email notifications.
20+
21+
`null` means files are only retrievable via `GET /v4/inbound-email/{id}/files`
22+
(pull delivery).
23+
"""
2024

2125
created_at: Optional[datetime] = None
2226
"""When the mailbox was created"""

tests/api_resources/test_inbound_email.py

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,16 @@ class TestInboundEmail:
2525
@pytest.mark.skip(reason="Mock server tests are disabled")
2626
@parametrize
2727
def test_method_create(self, client: CasParser) -> None:
28-
inbound_email = client.inbound_email.create(
29-
callback_url="https://api.yourapp.com/webhooks/cas-email",
30-
)
28+
inbound_email = client.inbound_email.create()
3129
assert_matches_type(InboundEmailCreateResponse, inbound_email, path=["response"])
3230

3331
@pytest.mark.skip(reason="Mock server tests are disabled")
3432
@parametrize
3533
def test_method_create_with_all_params(self, client: CasParser) -> None:
3634
inbound_email = client.inbound_email.create(
37-
callback_url="https://api.yourapp.com/webhooks/cas-email",
3835
alias="john-portfolio",
3936
allowed_sources=["cdsl", "nsdl"],
37+
callback_url="https://api.yourapp.com/webhooks/cas-email",
4038
metadata={
4139
"plan": "premium",
4240
"source": "onboarding",
@@ -48,9 +46,7 @@ def test_method_create_with_all_params(self, client: CasParser) -> None:
4846
@pytest.mark.skip(reason="Mock server tests are disabled")
4947
@parametrize
5048
def test_raw_response_create(self, client: CasParser) -> None:
51-
response = client.inbound_email.with_raw_response.create(
52-
callback_url="https://api.yourapp.com/webhooks/cas-email",
53-
)
49+
response = client.inbound_email.with_raw_response.create()
5450

5551
assert response.is_closed is True
5652
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -60,9 +56,7 @@ def test_raw_response_create(self, client: CasParser) -> None:
6056
@pytest.mark.skip(reason="Mock server tests are disabled")
6157
@parametrize
6258
def test_streaming_response_create(self, client: CasParser) -> None:
63-
with client.inbound_email.with_streaming_response.create(
64-
callback_url="https://api.yourapp.com/webhooks/cas-email",
65-
) as response:
59+
with client.inbound_email.with_streaming_response.create() as response:
6660
assert not response.is_closed
6761
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
6862

@@ -202,18 +196,16 @@ class TestAsyncInboundEmail:
202196
@pytest.mark.skip(reason="Mock server tests are disabled")
203197
@parametrize
204198
async def test_method_create(self, async_client: AsyncCasParser) -> None:
205-
inbound_email = await async_client.inbound_email.create(
206-
callback_url="https://api.yourapp.com/webhooks/cas-email",
207-
)
199+
inbound_email = await async_client.inbound_email.create()
208200
assert_matches_type(InboundEmailCreateResponse, inbound_email, path=["response"])
209201

210202
@pytest.mark.skip(reason="Mock server tests are disabled")
211203
@parametrize
212204
async def test_method_create_with_all_params(self, async_client: AsyncCasParser) -> None:
213205
inbound_email = await async_client.inbound_email.create(
214-
callback_url="https://api.yourapp.com/webhooks/cas-email",
215206
alias="john-portfolio",
216207
allowed_sources=["cdsl", "nsdl"],
208+
callback_url="https://api.yourapp.com/webhooks/cas-email",
217209
metadata={
218210
"plan": "premium",
219211
"source": "onboarding",
@@ -225,9 +217,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCasParser)
225217
@pytest.mark.skip(reason="Mock server tests are disabled")
226218
@parametrize
227219
async def test_raw_response_create(self, async_client: AsyncCasParser) -> None:
228-
response = await async_client.inbound_email.with_raw_response.create(
229-
callback_url="https://api.yourapp.com/webhooks/cas-email",
230-
)
220+
response = await async_client.inbound_email.with_raw_response.create()
231221

232222
assert response.is_closed is True
233223
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -237,9 +227,7 @@ async def test_raw_response_create(self, async_client: AsyncCasParser) -> None:
237227
@pytest.mark.skip(reason="Mock server tests are disabled")
238228
@parametrize
239229
async def test_streaming_response_create(self, async_client: AsyncCasParser) -> None:
240-
async with async_client.inbound_email.with_streaming_response.create(
241-
callback_url="https://api.yourapp.com/webhooks/cas-email",
242-
) as response:
230+
async with async_client.inbound_email.with_streaming_response.create() as response:
243231
assert not response.is_closed
244232
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
245233

0 commit comments

Comments
 (0)