# Call External API

> Call any HTTP API from API Maker with the call external API system API - one call, a list of calls in parallel or in sequence, with data copied from one answer into the next request.

Source: https://docs.apimaker.dev/v1/docs/apis-all/system-apis/system-generated-call-external-api.html

Makes HTTP calls to any URL from the server : one call, or a list of calls run in parallel or one after the other, with `preProcess` and `postProcess` rules which copy a value of one answer into the request of another.

| | |
|---|---|
| Method | POST |
| URL | `/api/system-api/admin/call-external-api` : `admin` is the user path of your account |
| Body | one call, an array of calls, or `{ type: "parallel" | "sequential", data: [ … ] }` |
| Answer | `data` : the response of the call, `{ statusCode, headers, body, … }`, or an array of them |
| From code | [`g.sys.system.callExternalApi`](https://docs.apimaker.dev/v1/examples/sys/system/callExternalApi.html) |

## One call

**Body**

```json
{
    "url": "https://api.example.com/customers",
    "method": "POST",
    "timeout": 5000,
    "headers": { "authorization": "Bearer …" },
    "queryParams": { "select": "first_name" },
    "body": { "first_name": "James", "last_name": "Bond" }
}
```

**Answer**

```json
{ "success": true, "statusCode": 200, "data": { "statusCode": 201, "headers": { "content-type": "application/json" }, "body": { "id": 42, "first_name": "James" } } }
```

| Key | Meaning |
|---|---|
| `url` | Required. The full URL. |
| `method` | `GET` (default), `HEAD`, `POST`, `PUT`, `DELETE`, `CONNECT`, `OPTIONS`, `TRACE`, `PATCH`. |
| `timeout` | Milliseconds. |
| `headers`, `queryParams`, `body` | What to send. |
| `id` | A name for this call, used by `preProcess` and `postProcess` of other calls. |
| `preProcess`, `postProcess` | Rules `{ from, to }` run before and after the call : `from` is a path starting with the `id` of a call (`saveApi.output.body.data.id`), `to` a path in a call (`setApi.body.customerId`). |
| `output` | Filled with the answer of the call, for the rules of the others. |

- The answer of a call is the response object of the HTTP client (undici) : `statusCode`, `headers`, and `body` parsed as JSON. A body which is not JSON comes as text.

## In parallel, in sequence

**Body : a save, then two calls at once with its result**

```json
[
    { "id": "saveApi", "url": "https://api.example.com/customers", "method": "POST", "body": { "first_name": "James" },
      "postProcess": [ { "from": "saveApi.output.body.id", "to": "setApi.body.customerId" } ] },
    { "type": "parallel", "data": [
        { "id": "setApi", "url": "https://api.example.com/preferences", "method": "PUT", "body": {} },
        { "id": "notify", "url": "https://hooks.example.com/new-customer", "method": "POST", "body": { "source": "shop" } }
    ] }
]
```

- The top level array runs in sequence ; `type: "parallel"` runs its `data` at once, `type: "sequential"` one after the other. Groups nest.
- The answer is an array with one entry per call, nested like the body.

## From code

```typescript
const resp = await g.sys.system.callExternalApi<{ id: number }>({ url: 'https://api.example.com/customers/42' });
if (resp.statusCode === 200) g.logger.log(resp.body.id);
```

- Custom APIs can also use any HTTP client of npm from the sandbox ; this API adds the parallel and sequential plans and the data copying without code.

## Access and settings

- Over HTTP, a system API answers once its [settings](https://docs.apimaker.dev/v1/docs/settings/systemApiSettings.html) give it `apiAccessType: TOKEN_ACCESS` (the token of an API user whose [group](https://docs.apimaker.dev/v1/docs/apis-security/api-group-permission.html) grants this system API, in `x-am-authorization`) or `IS_PUBLIC`. Without settings it is `NO_ACCESS` : your code calls it through `g.sys`, the admin panel tests it, and an HTTP call is refused.
- The settings can also cache the answer or require person tokens (`authProviders`) ; [pre and post hooks](https://docs.apimaker.dev/v1/docs/apis-all/hooks/preHook-api.html) run around it like around any API.
- The [request headers](https://docs.apimaker.dev/v1/docs/apis-all/header/requestHeader.html) apply : `x-am-response-case`, `x-am-content-type-response`, `x-am-internationalization`, `x-am-tenant-username`…

## Errors

| Code | When |
|---|---|
| `400` | The body is wrong : the message names the missing or invalid key, or a `url` which is not valid. |
| `401` | No valid API user token, or the API is `NO_ACCESS` : `You are not authorized to access this API.` |
| `403` | No group grants this system API. |

## Related

- [All APIs at a glance](https://docs.apimaker.dev/v1/docs/apis-all/overview.html) · [Response format](https://docs.apimaker.dev/v1/docs/apis-all/response-format.html) · [System API settings](https://docs.apimaker.dev/v1/docs/settings/systemApiSettings.html) · [System APIs from code](https://docs.apimaker.dev/v1/examples/sys/system/system.html)
