# Calling other services

> Every outbound HTTP call goes through `Http.*` — `Http.Get`/`Post`/`Put`/`Delete` take the URL as a value and hand back an `HttpResponse` you branch on, so a non-2xx is a value, not a throw. For a known API — a payment API, an exchange-rate feed, a shipping tracker — wrap those calls in an ordinary class with one typed method per endpoint; `osy import-api` writes that class from an OpenAPI document.

<!-- id: http-index · area: http · stability: stable · html: https://osysharp.com/reference/http/index/ -->

## Summary        {#summary}
When your app has to reach *out* to another service — a payment API, an exchange-rate feed, a shipping tracker, a
webhook — every call is made with the [Http.*](https://osysharp.com/reference/http/facade/) `Http.*`. What changes is how much you wrap it:

- A specific, known API → a typed [a typed HTTP client (a class over Http.*)](https://osysharp.com/reference/http/client/): an ordinary class whose methods are the API's endpoints, so every
  call site is type-checked.
- A URL built at runtime (a webhook target stored on a record) → call `Http.*` directly.

Either way the result is an [HttpResponse](https://osysharp.com/reference/http/response/), and a non-2xx status is an ordinary value you branch on — not an
exception you have to catch.

## Description    {#description}

### A typed client for a known API   {#client}
A [a typed HTTP client (a class over Http.*)](https://osysharp.com/reference/http/client/) is the one to reach for when you're integrating a specific, known API. It is an ordinary class: a
`BaseUrl` field, a credential field, one public method per endpoint (`TrackResult Track(string code)`), and a small
private `Get`/`Post` that calls `Http.*` and turns a non-2xx into a thrown error. The results are typed, so a call site
that expects the wrong shape is a compile error, not a 4am surprise. `osy import-api <spec>` generates exactly this
class from an OpenAPI document. Full shape and examples on [a typed HTTP client (a class over Http.*)](https://osysharp.com/reference/http/client/).

There is no retry at the transport: a call worth retrying is a durable step with a [`Backoff`](https://osysharp.com/reference/workflow/backoff/)
policy on it.

### The facade for a runtime URL   {#facade}
When the URL isn't knowable until runtime — a webhook target stored on a record, an endpoint you just discovered —
use the [Http.*](https://osysharp.com/reference/http/facade/). `Http.Get`/`Post`/`Put`/`Delete` take the URL as a value and return an [HttpResponse](https://osysharp.com/reference/http/response/), so
a webhook call is `var res = Http.Post(webhookUrl, body);` and you branch on `res.IsSuccess`.

### The response is a value, not a throw   {#response}
An [HttpResponse](https://osysharp.com/reference/http/response/) carries the status code, the body as text, and an `IsSuccess` flag (true for 2xx). A non-2xx —
a 404, a 500, a rate-limit 429 — is a normal return you inspect, not an exception. That is deliberate: an outbound
call fails in ordinary, expected ways, and forcing every one through a `try/catch` would be noise. You branch on the
status the same way you'd branch on any other value.

### Credentials belong in secrets   {#secrets}
An API key or client secret an outbound call needs is declared as a [secret](https://osysharp.com/reference/config/secrets/), never inlined. For
signing users in through a third party, or calling an API on a user's behalf, see [OAuth clients (app.OAuthClients)](https://osysharp.com/reference/config/oauth-clients/).

## See also       {#see-also}
- [a typed HTTP client (a class over Http.*)](https://osysharp.com/reference/http/client/) — a typed client: an ordinary class over `Http.*`, one method per endpoint
- [Backoff (retry policy)](https://osysharp.com/reference/workflow/backoff/) — retrying an outbound call, as a durable step with a retry policy
- [Http.*](https://osysharp.com/reference/http/facade/) — `Http.*` for a URL built at runtime
- [HttpResponse](https://osysharp.com/reference/http/response/) — the status / body / `IsSuccess` result you branch on
- [declaring secrets (app.Secrets)](https://osysharp.com/reference/config/secrets/) — where an API key lives; [OAuth clients (app.OAuthClients)](https://osysharp.com/reference/config/oauth-clients/) — third-party sign-in and delegated calls
