# Invoke endpoints from a script

Make HTTP requests to external endpoints from your scripts.

You can enable HTTP requests to an external endpoint from your script. Verify that your chosen extension point supports HTTP requests by checking the [extension point specification page](https://docs.stripe.com/extensions/extension-points.md).

## Add an endpoint to the app manifest

1. Open the `stripe-app.yaml` file in your app’s root directory. The file includes an `extensions` key with an `id` that matches the extension ID you chose for the generate command. Inside that object, there’s a `methods` key.
1. Add an `endpoints` key with the type `custom_http` at the same level as `methods`.
1. Provide an `id` and the endpoint `url`.

```yaml
extensions:
    - id: //your extension ID
      name: //your extension name
      methods:
      endpoints:
        - id: com.my_script.send_notifications
          type: custom_http
          managed_sandbox:
            url: https://your-url
```

To use the endpoint with live mode accounts, use `live` instead of `managed_sandbox`.

## Call the endpoint from your script

In your source file, use `endpointFetch` to call the endpoint. Make sure the `endpoint` value matches the `id` you specified in the manifest. This example uses a custom workflow action, but `endpointFetch` works the same way in any extension point that supports it.

Mark your `execute` method as `async` and use `await` with `endpointFetch` to ensure the HTTP request completes before your script returns.

### `endpointFetch` parameters

| **Parameter** | **Type**                                                        | **Required** | **Description**                                    |
| ------------- | --------------------------------------------------------------- | ------------ | -------------------------------------------------- |
| `endpoint`    | string                                                          | Yes          | The endpoint `id` declared in `stripe-app.yaml`.   |
| `path`        | string                                                          | Yes          | URL path appended to the endpoint base URL.        |
| `method`      | - `'GET'`
  - `'POST'`
  - `'PUT'`
  - `'DELETE'`
  - `'PATCH'` | Yes          | HTTP method for the request.                       |
| `body`        | string                                                          | No           | JSON-stringified request body.                     |
| `headers`     | `Record<string, string>`                                        | No           | Additional HTTP headers to include in the request. |

### Response

On success, `endpointFetch` returns an object with the following properties:

| **Property** | **Type**               | **Description**                                                                  |
| ------------ | ---------------------- | -------------------------------------------------------------------------------- |
| `ok`         | boolean                | `true` for successful responses.                                                 |
| `status`     | number                 | HTTP status code (200-299).                                                      |
| `body`       | - string
  - undefined | Response body as a JSON string. Parse it with `JSON.parse()` to access the data. |

```typescript
export default class MyCustomAction implements Extend.Workflows.CustomAction<MyCustomActionConfig> {
  async execute(
    request: Extend.Workflows.CustomAction.ExecuteCustomActionRequest,
    _config: MyCustomActionConfig,
    _context: Context
  ) {
    const customInput = request.customInput as Record<string, unknown>;

    await endpointFetch({
      endpoint: 'com.my_script.send_notifications',
      path: '/api/notifications',
      method: 'POST',
      body: JSON.stringify({
        message: `Payment received from ${customInput.name}`,
      }),
    });

    return {};
  }

  getFormState(
    _request: Extend.Workflows.CustomAction.GetFormStateRequest,
    _config: MyCustomActionConfig,
    _context: Context
  ) {
    return {
      values: _request.values,
      config: {},
    };
  }
}
```

The `request` object contains input specific to the extension point. In this custom workflow action example, `request.customInput` contains dynamic data mapped from the workflow trigger event, such as a customer name. You define these fields in `custom_input.schema.json` and reference them in `stripe-app.yaml` under the `execute` method.

The `config` object contains static values set once when the extension is configured, such as a notification channel. You define these fields in `config.schema.json`.

For more details, see [Custom actions](https://docs.stripe.com/workflows/custom-actions.md).

## Runtime considerations

`endpointFetch` throws an error for non-2xx responses and network failures. Wrap calls in a try-catch block to handle errors. Scripts that invoke endpoints have a 30-second timeout.

## Configure authorization

You can use token-based authorization or header-based authorization. First, [create a secret](https://docs.stripe.com/stripe-apps/store-secrets.md) on the account that runs the script. Then add an `auth` key to the app manifest `stripe-app.yaml` that specifies the authorization type and required values.

### Configure token-based authorization

Provide the `secret_name` in the `auth` key.

```yaml
      endpoints:
        - id: com.my_cool_script.endpoint_token
          type: custom_http
          managed_sandbox:
            url: https://example.com/api
            auth:
              secret_name: endpoint_bearer_token
              type: bearer_token
```

### Configure header-based authorization

Provide the `header_name` and `secret_name` in the `auth` key.

```yaml
      endpoints:
        - id: com.my_cool_script.endpoint_header
          type: custom_http
          managed_sandbox:
            url: https://example.com/api
            auth:
              secret_name: endpoint_header_secret
              type: header
              header_name: X-Foo-Header
```

## See also

- [Create an extension](https://docs.stripe.com/extensions/scripts/build-prorations-extension.md)
- [Extension points](https://docs.stripe.com/extensions/extension-points.md)
- [Store secrets](https://docs.stripe.com/stripe-apps/store-secrets.md)
