{"id":37965094,"url":"https://github.com/trycourier/courier-csharp","last_synced_at":"2026-01-27T23:54:59.588Z","repository":{"id":240788726,"uuid":"767183468","full_name":"trycourier/courier-csharp","owner":"trycourier","description":null,"archived":false,"fork":false,"pushed_at":"2026-01-10T04:19:16.000Z","size":2348,"stargazers_count":1,"open_issues_count":1,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-11T01:17:54.672Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/trycourier.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-03-04T21:07:40.000Z","updated_at":"2026-01-08T20:17:22.000Z","dependencies_parsed_at":"2026-01-06T19:09:05.078Z","dependency_job_id":null,"html_url":"https://github.com/trycourier/courier-csharp","commit_stats":null,"previous_names":["trycourier/courier-csharp"],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/trycourier/courier-csharp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trycourier%2Fcourier-csharp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trycourier%2Fcourier-csharp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trycourier%2Fcourier-csharp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trycourier%2Fcourier-csharp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/trycourier","download_url":"https://codeload.github.com/trycourier/courier-csharp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trycourier%2Fcourier-csharp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28480552,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-16T18:12:09.673Z","updated_at":"2026-01-16T18:12:13.255Z","avatar_url":"https://github.com/trycourier.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Courier C# API Library\n\nThe Courier C# SDK provides convenient access to the [Courier REST API](https://www.courier.com/docs) from applications written in C#.\n\nIt is generated with [Stainless](https://www.stainless.com/).\n\nThe REST API documentation can be found on [www.courier.com](https://www.courier.com/docs).\n\n## Installation\n\n```bash\ngit clone git@github.com:trycourier/courier-csharp.git\ndotnet add reference courier-csharp/src/Courier\n```\n\n## Requirements\n\nThis library requires .NET Standard 2.0 or later.\n\n## Usage\n\nSee the [`examples`](examples) directory for complete and runnable examples.\n\n```csharp\nusing System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Courier;\nusing Courier.Models;\nusing Courier.Models.Send;\n\nCourierClient client = new();\n\nSendMessageParams parameters = new()\n{\n    Message = new()\n    {\n        To = new UserRecipient() { UserID = \"your_user_id\" },\n        Template = \"your_template_id\",\n        Data = new Dictionary\u003cstring, JsonElement\u003e()\n        {\n            { \"foo\", JsonSerializer.SerializeToElement(\"bar\") }\n        },\n    },\n};\n\nvar response = await client.Send.Message(parameters);\n\nConsole.WriteLine(response);\n```\n\n## Client configuration\n\nConfigure the client using environment variables:\n\n```csharp\nusing Courier;\n\n// Configured using the COURIER_API_KEY and COURIER_BASE_URL environment variables\nCourierClient client = new();\n```\n\nOr manually:\n\n```csharp\nusing Courier;\n\nCourierClient client = new() { ApiKey = \"My API Key\" };\n```\n\nOr using a combination of the two approaches.\n\nSee this table for the available options:\n\n| Property  | Environment variable | Required | Default value               |\n| --------- | -------------------- | -------- | --------------------------- |\n| `ApiKey`  | `COURIER_API_KEY`    | true     | -                           |\n| `BaseUrl` | `COURIER_BASE_URL`   | true     | `\"https://api.courier.com\"` |\n\n### Modifying configuration\n\nTo temporarily use a modified client configuration, while reusing the same connection and thread pools, call `WithOptions` on any client or service:\n\n```csharp\nusing System;\n\nvar response = await client\n    .WithOptions(options =\u003e\n        options with\n        {\n            BaseUrl = \"https://example.com\",\n            Timeout = TimeSpan.FromSeconds(42),\n        }\n    )\n    .Send.Message(parameters);\n\nConsole.WriteLine(response);\n```\n\nUsing a [`with` expression](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/with-expression) makes it easy to construct the modified options.\n\nThe `WithOptions` method does not affect the original client or service.\n\n## Requests and responses\n\nTo send a request to the Courier API, build an instance of some `Params` class and pass it to the corresponding client method. When the response is received, it will be deserialized into an instance of a C# class.\n\nFor example, `client.Send.Message` should be called with an instance of `SendMessageParams`, and it will return an instance of `Task\u003cSendMessageResponse\u003e`.\n\n## Raw responses\n\nThe SDK defines methods that deserialize responses into instances of C# classes. However, these methods don't provide access to the response headers, status code, or the raw response body.\n\nTo access this data, prefix any HTTP method call on a client or service with `WithRawResponse`:\n\n```csharp\nvar response = await client.WithRawResponse.Send.Message(parameters);\nvar statusCode = response.StatusCode;\nvar headers = response.Headers;\n```\n\nThe raw `HttpResponseMessage` can also be accessed through the `RawMessage` property.\n\nFor non-streaming responses, you can deserialize the response into an instance of a C# class if needed:\n\n```csharp\nusing System;\nusing Courier.Models.Send;\n\nvar response = await client.WithRawResponse.Send.Message(parameters);\nSendMessageResponse deserialized = await response.Deserialize();\nConsole.WriteLine(deserialized);\n```\n\n## Error handling\n\nThe SDK throws custom unchecked exception types:\n\n- `CourierApiException`: Base class for API errors. See this table for which exception subclass is thrown for each HTTP status code:\n\n| Status | Exception                              |\n| ------ | -------------------------------------- |\n| 400    | `CourierBadRequestException`           |\n| 401    | `CourierUnauthorizedException`         |\n| 403    | `CourierForbiddenException`            |\n| 404    | `CourierNotFoundException`             |\n| 422    | `CourierUnprocessableEntityException`  |\n| 429    | `CourierRateLimitException`            |\n| 5xx    | `Courier5xxException`                  |\n| others | `CourierUnexpectedStatusCodeException` |\n\nAdditionally, all 4xx errors inherit from `Courier4xxException`.\n\nfalse\n\n- `CourierIOException`: I/O networking errors.\n\n- `CourierInvalidDataException`: Failure to interpret successfully parsed data. For example, when accessing a property that's supposed to be required, but the API unexpectedly omitted it from the response.\n\n- `CourierException`: Base class for all exceptions.\n\n## Network options\n\n### Retries\n\nThe SDK automatically retries 2 times by default, with a short exponential backoff between requests.\n\nOnly the following error types are retried:\n\n- Connection errors (for example, due to a network connectivity problem)\n- 408 Request Timeout\n- 409 Conflict\n- 429 Rate Limit\n- 5xx Internal\n\nThe API may also explicitly instruct the SDK to retry or not retry a request.\n\nTo set a custom number of retries, configure the client using the `MaxRetries` method:\n\n```csharp\nusing Courier;\n\nCourierClient client = new() { MaxRetries = 3 };\n```\n\nOr configure a single method call using [`WithOptions`](#modifying-configuration):\n\n```csharp\nusing System;\n\nvar response = await client\n    .WithOptions(options =\u003e\n        options with { MaxRetries = 3 }\n    )\n    .Send.Message(parameters);\n\nConsole.WriteLine(response);\n```\n\n### Timeouts\n\nRequests time out after 1 minute by default.\n\nTo set a custom timeout, configure the client using the `Timeout` option:\n\n```csharp\nusing System;\nusing Courier;\n\nCourierClient client = new() { Timeout = TimeSpan.FromSeconds(42) };\n```\n\nOr configure a single method call using [`WithOptions`](#modifying-configuration):\n\n```csharp\nusing System;\n\nvar response = await client\n    .WithOptions(options =\u003e\n        options with { Timeout = TimeSpan.FromSeconds(42) }\n    )\n    .Send.Message(parameters);\n\nConsole.WriteLine(response);\n```\n\n## Undocumented API functionality\n\nThe SDK is typed for convenient usage of the documented API. However, it also supports working with undocumented or not yet supported parts of the API.\n\n### Response validation\n\nIn rare cases, the API may return a response that doesn't match the expected type. For example, the SDK may expect a property to contain a `string`, but the API could return something else.\n\nBy default, the SDK will not throw an exception in this case. It will throw `CourierInvalidDataException` only if you directly access the property.\n\nIf you would prefer to check that the response is completely well-typed upfront, then either call `Validate`:\n\n```csharp\nvar response = client.Send.Message(parameters);\nresponse.Validate();\n```\n\nOr configure the client using the `ResponseValidation` option:\n\n```csharp\nusing Courier;\n\nCourierClient client = new() { ResponseValidation = true };\n```\n\nOr configure a single method call using [`WithOptions`](#modifying-configuration):\n\n```csharp\nusing System;\n\nvar response = await client\n    .WithOptions(options =\u003e\n        options with { ResponseValidation = true }\n    )\n    .Send.Message(parameters);\n\nConsole.WriteLine(response);\n```\n\n## Semantic versioning\n\nThis package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:\n\n1. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_\n2. Changes that we do not expect to impact the vast majority of users in practice.\n\nWe take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.\n\nWe are keen for your feedback; please open an [issue](https://www.github.com/trycourier/courier-csharp/issues) with questions, bugs, or suggestions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrycourier%2Fcourier-csharp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftrycourier%2Fcourier-csharp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrycourier%2Fcourier-csharp/lists"}