# Call External API Example

> Examples of calling other APIs from API Maker code - JSON, forms, file uploads, SOAP and XML, OAuth 2, retries, redirects, file downloads, and lists of calls in parallel or in sequence, in every language.

Source: https://docs.apimaker.dev/v4/examples/sys/system/callExternalApi.html

> **The code in every language**
>
> Each example is the inside of `main`, written in every [language](https://docs.apimaker.dev/v4/docs/languages/index.html) API Maker runs : pick yours in the tabs, and every page shows it from then on. The types a call takes (`GetAll`, `DeepItem`…) are those of `am` : `from am import GetAll` in Python, `use am::GetAll;` in Rust, `import am.GetAll;` in Java and Kotlin ; PHP and C# have them without an import, Go names them `am.GetAll`.

`g.sys.system.callExternalApi` calls the [call external API system API](https://docs.apimaker.dev/v4/docs/apis-all/system-apis/system-generated-call-external-api.html) from your code, whatever the settings of that API say about HTTP callers.

Call external API using global object 'g'.

### Simple call external apis

**TypeScript**

```typescript
await g.sys.system.callExternalApi([
    {
        "url": `your_url`,
        "method": "GET",
        "timeout": 5000,
        "queryParams": { "select": "first_name" },
        "headers": { "x-am-authorization": "TOKEN" },
    }
]);
```

**Python**

```python
await g.sys.system.call_external_apis([
    {
        'url': 'your_url',
        'method': 'GET',
        'timeout': 5000,
        'queryParams': {'select': 'first_name'},
        'headers': {'x-am-authorization': 'TOKEN'},
    },
])
```

**PHP**

```php
$g->sys->system->callExternalApis([
    [
        'url' => 'your_url',
        'method' => 'GET',
        'timeout' => 5000,
        'queryParams' => ['select' => 'first_name'],
        'headers' => ['x-am-authorization' => 'TOKEN'],
    ],
]);
```

**C#**

```csharp
await g.Sys.System.CallExternalApis(new JsonArray
{
    new JsonObject
    {
        ["url"] = "your_url",
        ["method"] = "GET",
        ["timeout"] = 5000,
        ["queryParams"] = new JsonObject { ["select"] = "first_name" },
        ["headers"] = new JsonObject { ["x-am-authorization"] = "TOKEN" },
    },
});
```

**Go**

```go
if _, err := g.Sys.System.CallExternalApis([]any{
	am.M{
		"url":         "your_url",
		"method":      "GET",
		"timeout":     5000,
		"queryParams": am.M{"select": "first_name"},
		"headers":     am.M{"x-am-authorization": "TOKEN"},
	},
}); err != nil {
	return nil, err
}
```

**Rust**

```rust
g.sys.system.call_external_apis(json!([
    {
        "url": "your_url",
        "method": "GET",
        "timeout": 5000,
        "queryParams": { "select": "first_name" },
        "headers": { "x-am-authorization": "TOKEN" },
    },
]))?;
```

**Java**

```java
g.sys.system.callExternalApis(List.of(
    Map.of(
        "url", "your_url",
        "method", "GET",
        "timeout", 5000,
        "queryParams", Map.of("select", "first_name"),
        "headers", Map.of("x-am-authorization", "TOKEN")
    )
));
```

**Kotlin**

```kotlin
g.sys.system.callExternalApis(listOf(
    mapOf(
        "url" to "your_url",
        "method" to "GET",
        "timeout" to 5000,
        "queryParams" to mapOf("select" to "first_name"),
        "headers" to mapOf("x-am-authorization" to "TOKEN"),
    ),
))
```

### Parallel type

- If the type is 'parallel' the external APIs are executed in parallel.

**TypeScript**

```typescript
await g.sys.system.callExternalApi([
    {
        url: "FULL_URL",
        method: "POST",
        body: [
            {
                first_name: "James",
                last_name: "Bond"
            }
        ],
        id: "saveApi",
        postProcess: [
            {
                from: "saveApi.output.body.data.first_name",
                to: "setApi.body.first_name"
            }
        ],
        queryParams: {
            // the query params of a URL are texts : deep is its JSON
            deep: '[{"s_key":"SOURCE_COLLECTION_COLUMN_NAME","t_key":"TARGET_COLLECTION_COLUMN_NAME","t_col":"TARGET_COLLECTION_NAME","select":"COLUMN_NAMES"}]',
            select: "COLUMN_NAMES",
            limit: 2,
            sort: "COLUMN_NAMES"
        },
        timeout: 1000,
        headers: { "x-am-authorization": "TOKEN" },
    },
    {
        type: 'parallel',
        data: [
            {
                url: "FULL_URL",
                method: 'PUT',
                body: {},
                id: "setApi",
                headers: { "x-am-authorization": "TOKEN" }
            },
            {
                url: "FULL_URL",
                method: 'GET',
                headers: { "x-am-authorization": "TOKEN" }
            }
        ]
    }
]);
```

**Python**

```python
await g.sys.system.call_external_apis([
    {
        'url': 'FULL_URL',
        'method': 'POST',
        'body': [
            {
                'first_name': 'James',
                'last_name': 'Bond',
            },
        ],
        'id': 'saveApi',
        'postProcess': [
            {
                'from': 'saveApi.output.body.data.first_name',
                'to': 'setApi.body.first_name',
            },
        ],
        'queryParams': {
            # the query params of a URL are texts : deep is its JSON
            'deep': '[{"s_key":"SOURCE_COLLECTION_COLUMN_NAME","t_key":"TARGET_COLLECTION_COLUMN_NAME","t_col":"TARGET_COLLECTION_NAME","select":"COLUMN_NAMES"}]',
            'select': 'COLUMN_NAMES',
            'limit': 2,
            'sort': 'COLUMN_NAMES',
        },
        'timeout': 1000,
        'headers': {'x-am-authorization': 'TOKEN'},
    },
    {
        'type': 'parallel',
        'data': [
            {
                'url': 'FULL_URL',
                'method': 'PUT',
                'body': {},
                'id': 'setApi',
                'headers': {'x-am-authorization': 'TOKEN'},
            },
            {
                'url': 'FULL_URL',
                'method': 'GET',
                'headers': {'x-am-authorization': 'TOKEN'},
            },
        ],
    },
])
```

**PHP**

```php
$g->sys->system->callExternalApis([
    [
        'url' => 'FULL_URL',
        'method' => 'POST',
        'body' => [
            [
                'first_name' => 'James',
                'last_name' => 'Bond',
            ],
        ],
        'id' => 'saveApi',
        'postProcess' => [
            [
                'from' => 'saveApi.output.body.data.first_name',
                'to' => 'setApi.body.first_name',
            ],
        ],
        'queryParams' => [
            // the query params of a URL are texts : deep is its JSON
            'deep' => '[{"s_key":"SOURCE_COLLECTION_COLUMN_NAME","t_key":"TARGET_COLLECTION_COLUMN_NAME","t_col":"TARGET_COLLECTION_NAME","select":"COLUMN_NAMES"}]',
            'select' => 'COLUMN_NAMES',
            'limit' => 2,
            'sort' => 'COLUMN_NAMES',
        ],
        'timeout' => 1000,
        'headers' => ['x-am-authorization' => 'TOKEN'],
    ],
    [
        'type' => 'parallel',
        'data' => [
            [
                'url' => 'FULL_URL',
                'method' => 'PUT',
                'body' => new AmObject(),
                'id' => 'setApi',
                'headers' => ['x-am-authorization' => 'TOKEN'],
            ],
            [
                'url' => 'FULL_URL',
                'method' => 'GET',
                'headers' => ['x-am-authorization' => 'TOKEN'],
            ],
        ],
    ],
]);
```

**C#**

```csharp
await g.Sys.System.CallExternalApis(new JsonArray
{
    new JsonObject
    {
        ["url"] = "FULL_URL",
        ["method"] = "POST",
        ["body"] = new JsonArray
        {
            new JsonObject
            {
                ["first_name"] = "James",
                ["last_name"] = "Bond",
            },
        },
        ["id"] = "saveApi",
        ["postProcess"] = new JsonArray
        {
            new JsonObject
            {
                ["from"] = "saveApi.output.body.data.first_name",
                ["to"] = "setApi.body.first_name",
            },
        },
        ["queryParams"] = new JsonObject
        {
            // the query params of a URL are texts : deep is its JSON
            ["deep"] = "[{\"s_key\":\"SOURCE_COLLECTION_COLUMN_NAME\",\"t_key\":\"TARGET_COLLECTION_COLUMN_NAME\",\"t_col\":\"TARGET_COLLECTION_NAME\",\"select\":\"COLUMN_NAMES\"}]",
            ["select"] = "COLUMN_NAMES",
            ["limit"] = 2,
            ["sort"] = "COLUMN_NAMES",
        },
        ["timeout"] = 1000,
        ["headers"] = new JsonObject { ["x-am-authorization"] = "TOKEN" },
    },
    new JsonObject
    {
        ["type"] = "parallel",
        ["data"] = new JsonArray
        {
            new JsonObject
            {
                ["url"] = "FULL_URL",
                ["method"] = "PUT",
                ["body"] = new JsonObject(),
                ["id"] = "setApi",
                ["headers"] = new JsonObject { ["x-am-authorization"] = "TOKEN" },
            },
            new JsonObject
            {
                ["url"] = "FULL_URL",
                ["method"] = "GET",
                ["headers"] = new JsonObject { ["x-am-authorization"] = "TOKEN" },
            },
        },
    },
});
```

**Go**

```go
if _, err := g.Sys.System.CallExternalApis([]any{
	am.M{
		"url":    "FULL_URL",
		"method": "POST",
		"body": []any{
			am.M{
				"first_name": "James",
				"last_name":  "Bond",
			},
		},
		"id": "saveApi",
		"postProcess": []any{
			am.M{
				"from": "saveApi.output.body.data.first_name",
				"to":   "setApi.body.first_name",
			},
		},
		"queryParams": am.M{
			// the query params of a URL are texts : deep is its JSON
			"deep":   "[{\"s_key\":\"SOURCE_COLLECTION_COLUMN_NAME\",\"t_key\":\"TARGET_COLLECTION_COLUMN_NAME\",\"t_col\":\"TARGET_COLLECTION_NAME\",\"select\":\"COLUMN_NAMES\"}]",
			"select": "COLUMN_NAMES",
			"limit":  2,
			"sort":   "COLUMN_NAMES",
		},
		"timeout": 1000,
		"headers": am.M{"x-am-authorization": "TOKEN"},
	},
	am.M{
		"type": "parallel",
		"data": []any{
			am.M{
				"url":     "FULL_URL",
				"method":  "PUT",
				"body":    am.M{},
				"id":      "setApi",
				"headers": am.M{"x-am-authorization": "TOKEN"},
			},
			am.M{
				"url":     "FULL_URL",
				"method":  "GET",
				"headers": am.M{"x-am-authorization": "TOKEN"},
			},
		},
	},
}); err != nil {
	return nil, err
}
```

**Rust**

```rust
g.sys.system.call_external_apis(json!([
    {
        "url": "FULL_URL",
        "method": "POST",
        "body": [
            {
                "first_name": "James",
                "last_name": "Bond",
            },
        ],
        "id": "saveApi",
        "postProcess": [
            {
                "from": "saveApi.output.body.data.first_name",
                "to": "setApi.body.first_name",
            },
        ],
        "queryParams": {
            // the query params of a URL are texts : deep is its JSON
            "deep": "[{\"s_key\":\"SOURCE_COLLECTION_COLUMN_NAME\",\"t_key\":\"TARGET_COLLECTION_COLUMN_NAME\",\"t_col\":\"TARGET_COLLECTION_NAME\",\"select\":\"COLUMN_NAMES\"}]",
            "select": "COLUMN_NAMES",
            "limit": 2,
            "sort": "COLUMN_NAMES",
        },
        "timeout": 1000,
        "headers": { "x-am-authorization": "TOKEN" },
    },
    {
        "type": "parallel",
        "data": [
            {
                "url": "FULL_URL",
                "method": "PUT",
                "body": {},
                "id": "setApi",
                "headers": { "x-am-authorization": "TOKEN" },
            },
            {
                "url": "FULL_URL",
                "method": "GET",
                "headers": { "x-am-authorization": "TOKEN" },
            },
        ],
    },
]))?;
```

**Java**

```java
g.sys.system.callExternalApis(List.of(
    Map.of(
        "url", "FULL_URL",
        "method", "POST",
        "body", List.of(
            Map.of(
                "first_name", "James",
                "last_name", "Bond"
            )
        ),
        "id", "saveApi",
        "postProcess", List.of(
            Map.of(
                "from", "saveApi.output.body.data.first_name",
                "to", "setApi.body.first_name"
            )
        ),
        "queryParams", Map.of(
            // the query params of a URL are texts : deep is its JSON
            "deep", "[{\"s_key\":\"SOURCE_COLLECTION_COLUMN_NAME\",\"t_key\":\"TARGET_COLLECTION_COLUMN_NAME\",\"t_col\":\"TARGET_COLLECTION_NAME\",\"select\":\"COLUMN_NAMES\"}]",
            "select", "COLUMN_NAMES",
            "limit", 2,
            "sort", "COLUMN_NAMES"
        ),
        "timeout", 1000,
        "headers", Map.of("x-am-authorization", "TOKEN")
    ),
    Map.of(
        "type", "parallel",
        "data", List.of(
            Map.of(
                "url", "FULL_URL",
                "method", "PUT",
                "body", JsonObject.of(),
                "id", "setApi",
                "headers", Map.of("x-am-authorization", "TOKEN")
            ),
            Map.of(
                "url", "FULL_URL",
                "method", "GET",
                "headers", Map.of("x-am-authorization", "TOKEN")
            )
        )
    )
));
```

**Kotlin**

```kotlin
g.sys.system.callExternalApis(listOf(
    mapOf(
        "url" to "FULL_URL",
        "method" to "POST",
        "body" to listOf(
            mapOf(
                "first_name" to "James",
                "last_name" to "Bond",
            ),
        ),
        "id" to "saveApi",
        "postProcess" to listOf(
            mapOf(
                "from" to "saveApi.output.body.data.first_name",
                "to" to "setApi.body.first_name",
            ),
        ),
        "queryParams" to mapOf(
            // the query params of a URL are texts : deep is its JSON
            "deep" to "[{\"s_key\":\"SOURCE_COLLECTION_COLUMN_NAME\",\"t_key\":\"TARGET_COLLECTION_COLUMN_NAME\",\"t_col\":\"TARGET_COLLECTION_NAME\",\"select\":\"COLUMN_NAMES\"}]",
            "select" to "COLUMN_NAMES",
            "limit" to 2,
            "sort" to "COLUMN_NAMES",
        ),
        "timeout" to 1000,
        "headers" to mapOf("x-am-authorization" to "TOKEN"),
    ),
    mapOf(
        "type" to "parallel",
        "data" to listOf(
            mapOf(
                "url" to "FULL_URL",
                "method" to "PUT",
                "body" to mapOf<String, Any?>(),
                "id" to "setApi",
                "headers" to mapOf("x-am-authorization" to "TOKEN"),
            ),
            mapOf(
                "url" to "FULL_URL",
                "method" to "GET",
                "headers" to mapOf("x-am-authorization" to "TOKEN"),
            ),
        ),
    ),
))
```

### Sequential type

- If the type is 'sequential' the API calls execute one by one.

**TypeScript**

```typescript
await g.sys.system.callExternalApi([
    {
        url: "your_url",
        method: "GET",
        timeout: 5000,
        queryParams: { "select": "first_name" },
        headers: { "x-am-meta": true },
        id: "getData",
        output: "any"
    },
    {
        type: "sequential",
        data: [
            {
                url: "your_url",
                method: "POST",
                body: {},
                id: "addData",
                preProcess: [
                    {
                        from: "getData.output.body.data",
                        to: "addData.body"
                    }
                ],
                headers: { "x-am-authorization": "TOKEN", "x-am-response-case": "capitalCase" }
            },
            {
                url: "your_url",
                method: "GET",
                headers: { "x-am-response-case": "capitalCase" }
            }
        ]
    }
]);
```

**Python**

```python
await g.sys.system.call_external_apis([
    {
        'url': 'your_url',
        'method': 'GET',
        'timeout': 5000,
        'queryParams': {'select': 'first_name'},
        'headers': {'x-am-meta': True},
        'id': 'getData',
        'output': 'any',
    },
    {
        'type': 'sequential',
        'data': [
            {
                'url': 'your_url',
                'method': 'POST',
                'body': {},
                'id': 'addData',
                'preProcess': [
                    {
                        'from': 'getData.output.body.data',
                        'to': 'addData.body',
                    },
                ],
                'headers': {'x-am-authorization': 'TOKEN', 'x-am-response-case': 'capitalCase'},
            },
            {
                'url': 'your_url',
                'method': 'GET',
                'headers': {'x-am-response-case': 'capitalCase'},
            },
        ],
    },
])
```

**PHP**

```php
$g->sys->system->callExternalApis([
    [
        'url' => 'your_url',
        'method' => 'GET',
        'timeout' => 5000,
        'queryParams' => ['select' => 'first_name'],
        'headers' => ['x-am-meta' => true],
        'id' => 'getData',
        'output' => 'any',
    ],
    [
        'type' => 'sequential',
        'data' => [
            [
                'url' => 'your_url',
                'method' => 'POST',
                'body' => new AmObject(),
                'id' => 'addData',
                'preProcess' => [
                    [
                        'from' => 'getData.output.body.data',
                        'to' => 'addData.body',
                    ],
                ],
                'headers' => ['x-am-authorization' => 'TOKEN', 'x-am-response-case' => 'capitalCase'],
            ],
            [
                'url' => 'your_url',
                'method' => 'GET',
                'headers' => ['x-am-response-case' => 'capitalCase'],
            ],
        ],
    ],
]);
```

**C#**

```csharp
await g.Sys.System.CallExternalApis(new JsonArray
{
    new JsonObject
    {
        ["url"] = "your_url",
        ["method"] = "GET",
        ["timeout"] = 5000,
        ["queryParams"] = new JsonObject { ["select"] = "first_name" },
        ["headers"] = new JsonObject { ["x-am-meta"] = true },
        ["id"] = "getData",
        ["output"] = "any",
    },
    new JsonObject
    {
        ["type"] = "sequential",
        ["data"] = new JsonArray
        {
            new JsonObject
            {
                ["url"] = "your_url",
                ["method"] = "POST",
                ["body"] = new JsonObject(),
                ["id"] = "addData",
                ["preProcess"] = new JsonArray
                {
                    new JsonObject
                    {
                        ["from"] = "getData.output.body.data",
                        ["to"] = "addData.body",
                    },
                },
                ["headers"] = new JsonObject { ["x-am-authorization"] = "TOKEN", ["x-am-response-case"] = "capitalCase" },
            },
            new JsonObject
            {
                ["url"] = "your_url",
                ["method"] = "GET",
                ["headers"] = new JsonObject { ["x-am-response-case"] = "capitalCase" },
            },
        },
    },
});
```

**Go**

```go
if _, err := g.Sys.System.CallExternalApis([]any{
	am.M{
		"url":         "your_url",
		"method":      "GET",
		"timeout":     5000,
		"queryParams": am.M{"select": "first_name"},
		"headers":     am.M{"x-am-meta": true},
		"id":          "getData",
		"output":      "any",
	},
	am.M{
		"type": "sequential",
		"data": []any{
			am.M{
				"url":    "your_url",
				"method": "POST",
				"body":   am.M{},
				"id":     "addData",
				"preProcess": []any{
					am.M{
						"from": "getData.output.body.data",
						"to":   "addData.body",
					},
				},
				"headers": am.M{"x-am-authorization": "TOKEN", "x-am-response-case": "capitalCase"},
			},
			am.M{
				"url":     "your_url",
				"method":  "GET",
				"headers": am.M{"x-am-response-case": "capitalCase"},
			},
		},
	},
}); err != nil {
	return nil, err
}
```

**Rust**

```rust
g.sys.system.call_external_apis(json!([
    {
        "url": "your_url",
        "method": "GET",
        "timeout": 5000,
        "queryParams": { "select": "first_name" },
        "headers": { "x-am-meta": true },
        "id": "getData",
        "output": "any",
    },
    {
        "type": "sequential",
        "data": [
            {
                "url": "your_url",
                "method": "POST",
                "body": {},
                "id": "addData",
                "preProcess": [
                    {
                        "from": "getData.output.body.data",
                        "to": "addData.body",
                    },
                ],
                "headers": { "x-am-authorization": "TOKEN", "x-am-response-case": "capitalCase" },
            },
            {
                "url": "your_url",
                "method": "GET",
                "headers": { "x-am-response-case": "capitalCase" },
            },
        ],
    },
]))?;
```

**Java**

```java
g.sys.system.callExternalApis(List.of(
    Map.of(
        "url", "your_url",
        "method", "GET",
        "timeout", 5000,
        "queryParams", Map.of("select", "first_name"),
        "headers", Map.of("x-am-meta", true),
        "id", "getData",
        "output", "any"
    ),
    Map.of(
        "type", "sequential",
        "data", List.of(
            Map.of(
                "url", "your_url",
                "method", "POST",
                "body", JsonObject.of(),
                "id", "addData",
                "preProcess", List.of(
                    Map.of(
                        "from", "getData.output.body.data",
                        "to", "addData.body"
                    )
                ),
                "headers", Map.of("x-am-authorization", "TOKEN", "x-am-response-case", "capitalCase")
            ),
            Map.of(
                "url", "your_url",
                "method", "GET",
                "headers", Map.of("x-am-response-case", "capitalCase")
            )
        )
    )
));
```

**Kotlin**

```kotlin
g.sys.system.callExternalApis(listOf(
    mapOf(
        "url" to "your_url",
        "method" to "GET",
        "timeout" to 5000,
        "queryParams" to mapOf("select" to "first_name"),
        "headers" to mapOf("x-am-meta" to true),
        "id" to "getData",
        "output" to "any",
    ),
    mapOf(
        "type" to "sequential",
        "data" to listOf(
            mapOf(
                "url" to "your_url",
                "method" to "POST",
                "body" to mapOf<String, Any?>(),
                "id" to "addData",
                "preProcess" to listOf(
                    mapOf(
                        "from" to "getData.output.body.data",
                        "to" to "addData.body",
                    ),
                ),
                "headers" to mapOf("x-am-authorization" to "TOKEN", "x-am-response-case" to "capitalCase"),
            ),
            mapOf(
                "url" to "your_url",
                "method" to "GET",
                "headers" to mapOf("x-am-response-case" to "capitalCase"),
            ),
        ),
    ),
))
```

### Path and query parameters, an API key, a form

- `pathParams` fills `:customerId` of the URL, `queryArrayFormat: 'repeat'` writes the list as `tags=web&tags=priority`, and `bodyType: 'form'` sends the body as `product=Pen&quantity=3`.
- `throwOnError` throws when the API answers with a status of 400 or above.

**TypeScript**

```typescript
const order = await g.sys.system.callExternalApi({
    url: 'https://api.example.com/customers/:customerId/orders',
    method: 'POST',
    pathParams: { customerId: 42 },
    queryParams: { tags: ['web', 'priority'] },
    queryArrayFormat: 'repeat',
    auth: { type: 'apiKey', name: 'x-api-key', value: 'API_KEY' },
    bodyType: 'form',
    body: { product: 'Pen', quantity: 3 },
    throwOnError: true,
});
g.logger.log(order.body.id);
```

**Python**

```python
order = await g.sys.system.call_external_api(
    'https://api.example.com/customers/:customerId/orders',
    method='POST',
    path_params={'customerId': 42},
    query_params={'tags': ['web', 'priority']},
    query_array_format='repeat',
    auth={'type': 'apiKey', 'name': 'x-api-key', 'value': 'API_KEY'},
    body_type='form',
    body={'product': 'Pen', 'quantity': 3},
    throw_on_error=True,
)
g.logger.log(order.body.id)
```

**PHP**

```php
$order = $g->sys->system->callExternalApi(
    'https://api.example.com/customers/:customerId/orders',
    method: 'POST',
    pathParams: ['customerId' => 42],
    queryParams: ['tags' => ['web', 'priority']],
    queryArrayFormat: 'repeat',
    auth: ['type' => 'apiKey', 'name' => 'x-api-key', 'value' => 'API_KEY'],
    bodyType: 'form',
    body: ['product' => 'Pen', 'quantity' => 3],
    throwOnError: true,
);
$g->logger->log($order->body->id);
```

**C#**

```csharp
var order = await g.Sys.System.CallExternalApi(new CallExternalApi("https://api.example.com/customers/:customerId/orders")
{
    Method = "POST",
    PathParams = new { customerId = 42 },
    QueryParams = new { tags = new[] { "web", "priority" } },
    QueryArrayFormat = "repeat",
    Auth = new { type = "apiKey", name = "x-api-key", value = "API_KEY" },
    BodyType = "form",
    Body = new { product = "Pen", quantity = 3 },
    ThrowOnError = true,
});
g.Logger.Log(order.Body?["id"]);
```

**Go**

```go
order, err := g.Sys.System.CallExternalApi(am.CallExternalApi{
	Url:              "https://api.example.com/customers/:customerId/orders",
	Method:           "POST",
	PathParams:       am.M{"customerId": 42},
	QueryParams:      am.M{"tags": []string{"web", "priority"}},
	QueryArrayFormat: "repeat",
	Auth:             am.M{"type": "apiKey", "name": "x-api-key", "value": "API_KEY"},
	BodyType:         "form",
	Body:             am.M{"product": "Pen", "quantity": 3},
	ThrowOnError:     true,
})
if err != nil {
	return nil, err
}
g.Logger.Log(am.AsM(order.Body).Int("id"))
```

**Rust**

```rust
let order = g.sys.system.call_external_api(
    CallExternalApi::new("https://api.example.com/customers/:customerId/orders")
        .method("POST")
        .path_params(json!({ "customerId": 42 }))
        .query_params(json!({ "tags": ["web", "priority"] }))
        .query_array_format("repeat")
        .auth(json!({ "type": "apiKey", "name": "x-api-key", "value": "API_KEY" }))
        .body_type("form")
        .body(json!({ "product": "Pen", "quantity": 3 }))
        .throw_on_error(true),
)?;
g.logger.log(&order.body["id"]);
```

**Java**

```java
ExternalApiResponse order = g.sys.system.callExternalApi(new CallExternalApi("https://api.example.com/customers/:customerId/orders")
    .method("POST")
    .pathParams(Map.of("customerId", 42))
    .queryParams(Map.of("tags", List.of("web", "priority")))
    .queryArrayFormat("repeat")
    .auth(Map.of("type", "apiKey", "name", "x-api-key", "value", "API_KEY"))
    .bodyType("form")
    .body(Map.of("product", "Pen", "quantity", 3))
    .throwOnError(true));
g.logger.log(JsonObject.from(order.getBody()).getLong("id"));
```

**Kotlin**

```kotlin
val order = g.sys.system.callExternalApi(
    CallExternalApi("https://api.example.com/customers/:customerId/orders")
        .method("POST")
        .pathParams(mapOf("customerId" to 42))
        .queryParams(mapOf("tags" to listOf("web", "priority")))
        .queryArrayFormat("repeat")
        .auth(mapOf("type" to "apiKey", "name" to "x-api-key", "value" to "API_KEY"))
        .bodyType("form")
        .body(mapOf("product" to "Pen", "quantity" to 3))
        .throwOnError(true),
)
g.logger.log(JsonObject.from(order.body).getLong("id"))
```

### Upload files

- `bodyType: 'multipart'` sends a form of several parts : every key of the body is a field, and `{ file }` a file of the uploads folder.
- A file a form sent to your custom API is sent on as it is : `document: g.req.files.files[0]`.

**TypeScript**

```typescript
await g.sys.system.callExternalApi({
    url: 'https://api.example.com/documents',
    method: 'POST',
    auth: { type: 'bearer', token: 'TOKEN' },
    bodyType: 'multipart',
    body: {
        title: 'Contract',
        // a file of the uploads folder
        document: { file: 'contracts/42.pdf' },
        // a text sent as a file
        note: { content: 'Signed on site', fileName: 'note.txt' },
    },
});
```

**Python**

```python
await g.sys.system.call_external_api(
    'https://api.example.com/documents',
    method='POST',
    auth={'type': 'bearer', 'token': 'TOKEN'},
    body_type='multipart',
    body={
        'title': 'Contract',
        # a file of the uploads folder
        'document': {'file': 'contracts/42.pdf'},
        # a text sent as a file
        'note': {'content': 'Signed on site', 'fileName': 'note.txt'},
    },
)
```

**PHP**

```php
$g->sys->system->callExternalApi(
    'https://api.example.com/documents',
    method: 'POST',
    auth: ['type' => 'bearer', 'token' => 'TOKEN'],
    bodyType: 'multipart',
    body: [
        'title' => 'Contract',
        // a file of the uploads folder
        'document' => ['file' => 'contracts/42.pdf'],
        // a text sent as a file
        'note' => ['content' => 'Signed on site', 'fileName' => 'note.txt'],
    ],
);
```

**C#**

```csharp
await g.Sys.System.CallExternalApi(new CallExternalApi("https://api.example.com/documents")
{
    Method = "POST",
    Auth = new { type = "bearer", token = "TOKEN" },
    BodyType = "multipart",
    Body = new
    {
        title = "Contract",
        // a file of the uploads folder
        document = new { file = "contracts/42.pdf" },
        // a text sent as a file
        note = new { content = "Signed on site", fileName = "note.txt" },
    },
});
```

**Go**

```go
if _, err := g.Sys.System.CallExternalApi(am.CallExternalApi{
	Url:      "https://api.example.com/documents",
	Method:   "POST",
	Auth:     am.M{"type": "bearer", "token": "TOKEN"},
	BodyType: "multipart",
	Body: am.M{
		"title": "Contract",
		// a file of the uploads folder
		"document": am.M{"file": "contracts/42.pdf"},
		// a text sent as a file
		"note": am.M{"content": "Signed on site", "fileName": "note.txt"},
	},
}); err != nil {
	return nil, err
}
```

**Rust**

```rust
g.sys.system.call_external_api(
    CallExternalApi::new("https://api.example.com/documents")
        .method("POST")
        .auth(json!({ "type": "bearer", "token": "TOKEN" }))
        .body_type("multipart")
        .body(json!({
            "title": "Contract",
            // a file of the uploads folder
            "document": { "file": "contracts/42.pdf" },
            // a text sent as a file
            "note": { "content": "Signed on site", "fileName": "note.txt" },
        })),
)?;
```

**Java**

```java
g.sys.system.callExternalApi(new CallExternalApi("https://api.example.com/documents")
    .method("POST")
    .auth(Map.of("type", "bearer", "token", "TOKEN"))
    .bodyType("multipart")
    .body(Map.of(
        "title", "Contract",
        // a file of the uploads folder
        "document", Map.of("file", "contracts/42.pdf"),
        // a text sent as a file
        "note", Map.of("content", "Signed on site", "fileName", "note.txt"))));
```

**Kotlin**

```kotlin
g.sys.system.callExternalApi(
    CallExternalApi("https://api.example.com/documents")
        .method("POST")
        .auth(mapOf("type" to "bearer", "token" to "TOKEN"))
        .bodyType("multipart")
        .body(
            mapOf(
                "title" to "Contract",
                // a file of the uploads folder
                "document" to mapOf("file" to "contracts/42.pdf"),
                // a text sent as a file
                "note" to mapOf("content" to "Signed on site", "fileName" to "note.txt"),
            ),
        ),
)
```

### XML and SOAP

- `bodyType: 'xml'` sends the text of the body as it is, `responseType: 'text'` gives the answer as its text, whatever it holds.
- `retry` sends the request again when it got no answer, or one of the statuses 408, 429, 500, 502, 503 and 504.

**TypeScript**

```typescript
const rate = await g.sys.system.callExternalApi({
    url: 'https://soap.example.com/service',
    method: 'POST',
    bodyType: 'xml',
    headers: { 'content-type': 'text/xml; charset=utf-8', SOAPAction: 'urn:GetRate' },
    body: "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body><GetRate/></soap:Body></soap:Envelope>",
    responseType: 'text',
    retry: { count: 3, delay: 500 },
});
g.logger.log(rate.statusCode);
```

**Python**

```python
rate = await g.sys.system.call_external_api(
    'https://soap.example.com/service',
    method='POST',
    body_type='xml',
    headers={'content-type': 'text/xml; charset=utf-8', 'SOAPAction': 'urn:GetRate'},
    body="<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body><GetRate/></soap:Body></soap:Envelope>",
    response_type='text',
    retry={'count': 3, 'delay': 500},
)
g.logger.log(rate.status_code)
```

**PHP**

```php
$rate = $g->sys->system->callExternalApi(
    'https://soap.example.com/service',
    method: 'POST',
    bodyType: 'xml',
    headers: ['content-type' => 'text/xml; charset=utf-8', 'SOAPAction' => 'urn:GetRate'],
    body: "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body><GetRate/></soap:Body></soap:Envelope>",
    responseType: 'text',
    retry: ['count' => 3, 'delay' => 500],
);
$g->logger->log($rate->statusCode);
```

**C#**

```csharp
var rate = await g.Sys.System.CallExternalApi(new CallExternalApi("https://soap.example.com/service")
{
    Method = "POST",
    BodyType = "xml",
    Headers = new JsonObject { ["content-type"] = "text/xml; charset=utf-8", ["SOAPAction"] = "urn:GetRate" },
    Body = "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body><GetRate/></soap:Body></soap:Envelope>",
    ResponseType = "text",
    Retry = new { count = 3, delay = 500 },
});
g.Logger.Log(rate.StatusCode);
```

**Go**

```go
rate, err := g.Sys.System.CallExternalApi(am.CallExternalApi{
	Url:          "https://soap.example.com/service",
	Method:       "POST",
	BodyType:     "xml",
	Headers:      am.M{"content-type": "text/xml; charset=utf-8", "SOAPAction": "urn:GetRate"},
	Body:         "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body><GetRate/></soap:Body></soap:Envelope>",
	ResponseType: "text",
	Retry:        am.M{"count": 3, "delay": 500},
})
if err != nil {
	return nil, err
}
g.Logger.Log(rate.StatusCode)
```

**Rust**

```rust
let rate = g.sys.system.call_external_api(
    CallExternalApi::new("https://soap.example.com/service")
        .method("POST")
        .body_type("xml")
        .headers(json!({ "content-type": "text/xml; charset=utf-8", "SOAPAction": "urn:GetRate" }))
        .body("<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body><GetRate/></soap:Body></soap:Envelope>")
        .response_type("text")
        .retry(json!({ "count": 3, "delay": 500 })),
)?;
g.logger.log(json!(rate.status_code));
```

**Java**

```java
ExternalApiResponse rate = g.sys.system.callExternalApi(new CallExternalApi("https://soap.example.com/service")
    .method("POST")
    .bodyType("xml")
    .headers(Map.of("content-type", "text/xml; charset=utf-8", "SOAPAction", "urn:GetRate"))
    .body("<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body><GetRate/></soap:Body></soap:Envelope>")
    .responseType("text")
    .retry(Map.of("count", 3, "delay", 500)));
g.logger.log(rate.getStatusCode());
```

**Kotlin**

```kotlin
val rate = g.sys.system.callExternalApi(
    CallExternalApi("https://soap.example.com/service")
        .method("POST")
        .bodyType("xml")
        .headers(mapOf("content-type" to "text/xml; charset=utf-8", "SOAPAction" to "urn:GetRate"))
        .body("<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body><GetRate/></soap:Body></soap:Envelope>")
        .responseType("text")
        .retry(mapOf("count" to 3, "delay" to 500)),
)
g.logger.log(rate.statusCode)
```

### OAuth 2, redirects and retries

- The token is asked of `tokenUrl` with the id and the secret of the client, kept until it expires, and asked for again when the API refuses it.
- `ok` is `true` when the status of the answer is 200 to 299.

**TypeScript**

```typescript
const reports = await g.sys.system.callExternalApi({
    url: 'https://api.example.com/reports',
    auth: {
        type: 'oauth2',
        tokenUrl: 'https://login.example.com/oauth/token',
        clientId: 'CLIENT_ID',
        clientSecret: 'CLIENT_SECRET',
        scope: 'reports.read',
    },
    followRedirects: true,
    retry: 3,
    timeout: 10000,
});
if (!reports.ok) g.logger.log(reports.statusCode);
```

**Python**

```python
reports = await g.sys.system.call_external_api(
    'https://api.example.com/reports',
    auth={
        'type': 'oauth2',
        'tokenUrl': 'https://login.example.com/oauth/token',
        'clientId': 'CLIENT_ID',
        'clientSecret': 'CLIENT_SECRET',
        'scope': 'reports.read',
    },
    follow_redirects=True,
    retry=3,
    timeout=10000,
)
if not reports.ok:
    g.logger.log(reports.status_code)
```

**PHP**

```php
$reports = $g->sys->system->callExternalApi(
    'https://api.example.com/reports',
    auth: [
        'type' => 'oauth2',
        'tokenUrl' => 'https://login.example.com/oauth/token',
        'clientId' => 'CLIENT_ID',
        'clientSecret' => 'CLIENT_SECRET',
        'scope' => 'reports.read',
    ],
    followRedirects: true,
    retry: 3,
    timeout: 10000,
);
if (!$reports->ok) {
    $g->logger->log($reports->statusCode);
}
```

**C#**

```csharp
var reports = await g.Sys.System.CallExternalApi(new CallExternalApi("https://api.example.com/reports")
{
    Auth = new
    {
        type = "oauth2",
        tokenUrl = "https://login.example.com/oauth/token",
        clientId = "CLIENT_ID",
        clientSecret = "CLIENT_SECRET",
        scope = "reports.read",
    },
    FollowRedirects = true,
    Retry = 3,
    Timeout = 10000,
});
if (!reports.Ok) g.Logger.Log(reports.StatusCode);
```

**Go**

```go
reports, err := g.Sys.System.CallExternalApi(am.CallExternalApi{
	Url: "https://api.example.com/reports",
	Auth: am.M{
		"type":         "oauth2",
		"tokenUrl":     "https://login.example.com/oauth/token",
		"clientId":     "CLIENT_ID",
		"clientSecret": "CLIENT_SECRET",
		"scope":        "reports.read",
	},
	FollowRedirects: true,
	Retry:           3,
	Timeout:         10000,
})
if err != nil {
	return nil, err
}
if !reports.Ok {
	g.Logger.Log(reports.StatusCode)
}
```

**Rust**

```rust
let reports = g.sys.system.call_external_api(
    CallExternalApi::new("https://api.example.com/reports")
        .auth(json!({
            "type": "oauth2",
            "tokenUrl": "https://login.example.com/oauth/token",
            "clientId": "CLIENT_ID",
            "clientSecret": "CLIENT_SECRET",
            "scope": "reports.read",
        }))
        .follow_redirects(true)
        .retry(3)
        .timeout(10000),
)?;
if reports.ok != Some(true) {
    g.logger.log(json!(reports.status_code));
}
```

**Java**

```java
ExternalApiResponse reports = g.sys.system.callExternalApi(new CallExternalApi("https://api.example.com/reports")
    .auth(Map.of(
        "type", "oauth2",
        "tokenUrl", "https://login.example.com/oauth/token",
        "clientId", "CLIENT_ID",
        "clientSecret", "CLIENT_SECRET",
        "scope", "reports.read"))
    .followRedirects(true)
    .retry(3)
    .timeout(10000));
if (!reports.isOk()) g.logger.log(reports.getStatusCode());
```

**Kotlin**

```kotlin
val reports = g.sys.system.callExternalApi(
    CallExternalApi("https://api.example.com/reports")
        .auth(
            mapOf(
                "type" to "oauth2",
                "tokenUrl" to "https://login.example.com/oauth/token",
                "clientId" to "CLIENT_ID",
                "clientSecret" to "CLIENT_SECRET",
                "scope" to "reports.read",
            ),
        )
        .followRedirects(true)
        .retry(3)
        .timeout(10000),
)
if (!reports.isOk) g.logger.log(reports.statusCode)
```

### Download a file

- `download` saves the body of the answer as a file of the uploads folder, and the answer has `file` : its `path` in the uploads folder, its `name`, its `size` and its `contentType`.
- Your code reads the file at `uploads/` + `file.path`. A custom API sends it to its caller by returning `{ __am__downloadFilePath: saved.file.path }`.
- Redirects are followed. When the status of the answer is not 200 to 299 there is no `file` : the answer is given as any other.

**TypeScript**

```typescript
const saved = await g.sys.system.callExternalApi({
    url: 'https://api.example.com/invoices/42/pdf',
    download: { path: 'invoices/42.pdf', fileName: 'Invoice 42.pdf' },
});
g.logger.log(saved.file.size);
```

**Python**

```python
saved = await g.sys.system.call_external_api(
    'https://api.example.com/invoices/42/pdf',
    download={'path': 'invoices/42.pdf', 'fileName': 'Invoice 42.pdf'},
)
g.logger.log(saved.file.size)
```

**PHP**

```php
$saved = $g->sys->system->callExternalApi(
    'https://api.example.com/invoices/42/pdf',
    download: ['path' => 'invoices/42.pdf', 'fileName' => 'Invoice 42.pdf'],
);
$g->logger->log($saved->file->size);
```

**C#**

```csharp
var saved = await g.Sys.System.CallExternalApi(new CallExternalApi("https://api.example.com/invoices/42/pdf")
{
    Download = new { path = "invoices/42.pdf", fileName = "Invoice 42.pdf" },
});
g.Logger.Log(saved.File["size"]);
```

**Go**

```go
saved, err := g.Sys.System.CallExternalApi(am.CallExternalApi{
	Url:      "https://api.example.com/invoices/42/pdf",
	Download: am.M{"path": "invoices/42.pdf", "fileName": "Invoice 42.pdf"},
})
if err != nil {
	return nil, err
}
g.Logger.Log(saved.File.Int("size"))
```

**Rust**

```rust
let saved = g.sys.system.call_external_api(
    CallExternalApi::new("https://api.example.com/invoices/42/pdf")
        .download(json!({ "path": "invoices/42.pdf", "fileName": "Invoice 42.pdf" })),
)?;
g.logger.log(&saved.file["size"]);
```

**Java**

```java
ExternalApiResponse saved = g.sys.system.callExternalApi(new CallExternalApi("https://api.example.com/invoices/42/pdf")
    .download(Map.of("path", "invoices/42.pdf", "fileName", "Invoice 42.pdf")));
g.logger.log(saved.getFile().getLong("size"));
```

**Kotlin**

```kotlin
val saved = g.sys.system.callExternalApi(
    CallExternalApi("https://api.example.com/invoices/42/pdf")
        .download(mapOf("path" to "invoices/42.pdf", "fileName" to "Invoice 42.pdf")),
)
g.logger.log(saved.file.getLong("size"))
```

### Bytes

- `responseType: 'base64'` gives the bytes of the answer as Base64 text, in every language. `'buffer'` gives a `Buffer` in TypeScript.
- `bodyType: 'binary'` sends bytes : their Base64 text, a `Buffer`, or `{ file }` for a file of the uploads folder.

**TypeScript**

```typescript
const picture = await g.sys.system.callExternalApi({ url: 'https://api.example.com/logo.png', responseType: 'base64' });
await g.sys.system.callExternalApi({
    url: 'https://storage.example.com/bucket/logo.png',
    method: 'PUT',
    bodyType: 'binary',
    headers: { 'content-type': 'image/png' },
    body: picture.body,
});
```

**Python**

```python
picture = await g.sys.system.call_external_api('https://api.example.com/logo.png', response_type='base64')
await g.sys.system.call_external_api(
    'https://storage.example.com/bucket/logo.png',
    method='PUT',
    body_type='binary',
    headers={'content-type': 'image/png'},
    body=picture.body,
)
```

**PHP**

```php
$picture = $g->sys->system->callExternalApi('https://api.example.com/logo.png', responseType: 'base64');
$g->sys->system->callExternalApi(
    'https://storage.example.com/bucket/logo.png',
    method: 'PUT',
    bodyType: 'binary',
    headers: ['content-type' => 'image/png'],
    body: $picture->body,
);
```

**C#**

```csharp
var picture = await g.Sys.System.CallExternalApi(new CallExternalApi("https://api.example.com/logo.png") { ResponseType = "base64" });
await g.Sys.System.CallExternalApi(new CallExternalApi("https://storage.example.com/bucket/logo.png")
{
    Method = "PUT",
    BodyType = "binary",
    Headers = new JsonObject { ["content-type"] = "image/png" },
    Body = picture.Body,
});
```

**Go**

```go
picture, err := g.Sys.System.CallExternalApi(am.CallExternalApi{Url: "https://api.example.com/logo.png", ResponseType: "base64"})
if err != nil {
	return nil, err
}
if _, err := g.Sys.System.CallExternalApi(am.CallExternalApi{
	Url:      "https://storage.example.com/bucket/logo.png",
	Method:   "PUT",
	BodyType: "binary",
	Headers:  am.M{"content-type": "image/png"},
	Body:     picture.Body,
}); err != nil {
	return nil, err
}
```

**Rust**

```rust
let picture = g.sys.system.call_external_api(CallExternalApi::new("https://api.example.com/logo.png").response_type("base64"))?;
g.sys.system.call_external_api(
    CallExternalApi::new("https://storage.example.com/bucket/logo.png")
        .method("PUT")
        .body_type("binary")
        .headers(json!({ "content-type": "image/png" }))
        .body(picture.body),
)?;
```

**Java**

```java
ExternalApiResponse picture = g.sys.system.callExternalApi(new CallExternalApi("https://api.example.com/logo.png").responseType("base64"));
g.sys.system.callExternalApi(new CallExternalApi("https://storage.example.com/bucket/logo.png")
    .method("PUT")
    .bodyType("binary")
    .headers(Map.of("content-type", "image/png"))
    .body(picture.getBody()));
```

**Kotlin**

```kotlin
val picture = g.sys.system.callExternalApi(CallExternalApi("https://api.example.com/logo.png").responseType("base64"))
g.sys.system.callExternalApi(
    CallExternalApi("https://storage.example.com/bucket/logo.png")
        .method("PUT")
        .bodyType("binary")
        .headers(mapOf("content-type" to "image/png"))
        .body(picture.body),
)
```

### A call which may fail

- `allowFailure` : when the call fails, its answer is `{ statusCode: 0, ok: false, error: { message } }`, and the calls after it run.
- `throwOnError` : a status of 400 or above ends the list with an error. `retry: 2` sends the request two more times first.

**TypeScript**

```typescript
await g.sys.system.callExternalApi([
    {
        id: "audit",
        url: "https://audit.example.com/events",
        method: "POST",
        body: { event: "order" },
        timeout: 2000,
        allowFailure: true
    },
    {
        id: "order",
        url: "https://api.example.com/orders",
        method: "POST",
        body: { product: "Pen" },
        retry: 2,
        throwOnError: true
    }
]);
```

**Python**

```python
await g.sys.system.call_external_apis([
    {
        'id': 'audit',
        'url': 'https://audit.example.com/events',
        'method': 'POST',
        'body': {'event': 'order'},
        'timeout': 2000,
        'allowFailure': True,
    },
    {
        'id': 'order',
        'url': 'https://api.example.com/orders',
        'method': 'POST',
        'body': {'product': 'Pen'},
        'retry': 2,
        'throwOnError': True,
    },
])
```

**PHP**

```php
$g->sys->system->callExternalApis([
    [
        'id' => 'audit',
        'url' => 'https://audit.example.com/events',
        'method' => 'POST',
        'body' => ['event' => 'order'],
        'timeout' => 2000,
        'allowFailure' => true,
    ],
    [
        'id' => 'order',
        'url' => 'https://api.example.com/orders',
        'method' => 'POST',
        'body' => ['product' => 'Pen'],
        'retry' => 2,
        'throwOnError' => true,
    ],
]);
```

**C#**

```csharp
await g.Sys.System.CallExternalApis(new JsonArray
{
    new JsonObject
    {
        ["id"] = "audit",
        ["url"] = "https://audit.example.com/events",
        ["method"] = "POST",
        ["body"] = new JsonObject { ["event"] = "order" },
        ["timeout"] = 2000,
        ["allowFailure"] = true,
    },
    new JsonObject
    {
        ["id"] = "order",
        ["url"] = "https://api.example.com/orders",
        ["method"] = "POST",
        ["body"] = new JsonObject { ["product"] = "Pen" },
        ["retry"] = 2,
        ["throwOnError"] = true,
    },
});
```

**Go**

```go
if _, err := g.Sys.System.CallExternalApis([]any{
	am.M{
		"id":           "audit",
		"url":          "https://audit.example.com/events",
		"method":       "POST",
		"body":         am.M{"event": "order"},
		"timeout":      2000,
		"allowFailure": true,
	},
	am.M{
		"id":           "order",
		"url":          "https://api.example.com/orders",
		"method":       "POST",
		"body":         am.M{"product": "Pen"},
		"retry":        2,
		"throwOnError": true,
	},
}); err != nil {
	return nil, err
}
```

**Rust**

```rust
g.sys.system.call_external_apis(json!([
    {
        "id": "audit",
        "url": "https://audit.example.com/events",
        "method": "POST",
        "body": { "event": "order" },
        "timeout": 2000,
        "allowFailure": true,
    },
    {
        "id": "order",
        "url": "https://api.example.com/orders",
        "method": "POST",
        "body": { "product": "Pen" },
        "retry": 2,
        "throwOnError": true,
    },
]))?;
```

**Java**

```java
g.sys.system.callExternalApis(List.of(
    Map.of(
        "id", "audit",
        "url", "https://audit.example.com/events",
        "method", "POST",
        "body", Map.of("event", "order"),
        "timeout", 2000,
        "allowFailure", true
    ),
    Map.of(
        "id", "order",
        "url", "https://api.example.com/orders",
        "method", "POST",
        "body", Map.of("product", "Pen"),
        "retry", 2,
        "throwOnError", true
    )
));
```

**Kotlin**

```kotlin
g.sys.system.callExternalApis(listOf(
    mapOf(
        "id" to "audit",
        "url" to "https://audit.example.com/events",
        "method" to "POST",
        "body" to mapOf("event" to "order"),
        "timeout" to 2000,
        "allowFailure" to true,
    ),
    mapOf(
        "id" to "order",
        "url" to "https://api.example.com/orders",
        "method" to "POST",
        "body" to mapOf("product" to "Pen"),
        "retry" to 2,
        "throwOnError" to true,
    ),
))
```

## Related

- [Call external api system API](https://docs.apimaker.dev/v4/docs/apis-all/system-apis/system-generated-call-external-api.html) · [All system APIs from code](https://docs.apimaker.dev/v4/examples/sys/system/system.html) · [The global object g](https://docs.apimaker.dev/v4/docs/pre-defined-terms/global-object-g.html)
