> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qonto.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Proxy endpoint implementation

# Background

The Qonto API authenticates users with an access token. This token must be kept secret and should never be exposed in
client-side code. To achieve this, the Embed API and SDK provide a secure mechanism to proxy requests through your
server.

<Info>
  In addition to the access token, the staging token is another piece of
  sensitive information that must be kept secret. When using the staging
  environment, include the staging token in the request headers when calling the
  Qonto API.
</Info>

# System Overview

The Qonto API provides a proxy endpoint that dispatches requests to other Qonto API endpoints. It expects a
base64-encoded string that describes the call to be made to the target endpoint. Upon receiving this request, the proxy
endpoint decodes the string and makes the request to the Qonto API on your behalf. The response is then returned to the
caller, also base64-encoded.

When using the Qonto SDK, you don't need to handle the encoding/decoding of calls, the SDK manages this automatically.

The overall flow involves creating an intermediary endpoint on your server that forwards requests prepared by the SDK to
the Qonto API while including the access token in the request headers. This way, client-side code never has access to
the access token, keeping it secure on your server.

```mermaid theme={null}
sequenceDiagram
  participant FE as Your frontend
  participant SDK as Embed SDK
  participant YBE as Your backend
  participant QAPI as Qonto Embed API

  FE ->> SDK: initialize(proxyEndpointDescriptor)
  FE ->> SDK: sdk.performOperation()
  Note right of SDK: The SDK calls your intermediary endpoint directly

  SDK ->> YBE: Call your intermediary endpoint
  YBE ->> QAPI: Add accessToken + propagate call
  QAPI ->> QAPI: Call actual endpoint to perform operation
  QAPI ->> YBE: Encoded response
  YBE ->> SDK: Encoded response
  SDK ->> FE: Operation result
```

Here are the steps involved in the process shown in the diagram above:

<Steps>
  <Step title="Define the proxyEndpointDescriptor">
    Initialize the SDK with a `proxyEndpointDescriptor` parameter that describes
    your intermediary endpoint. Since only you know your endpoint details,
    providing this descriptor is how the SDK knows how to reach your
    intermediary endpoint. The descriptor must include at least a `path` and
    `method`. Optionally, you can provide an `options` object with fields such
    as `options.headers` to include custom headers in the request.
  </Step>

  <Step title="Use the SDK normally">
    Once the SDK is initialized, you can use it as you normally would. Call any
    SDK function and await the response from your application.
  </Step>

  <Step title="The SDK uses the proxyEndpointDescriptor to call your intermediary endpoint">
    When the SDK prepares the call to the API endpoint related to the function
    you called, it encodes the request and calls your intermediary endpoint
    using the `path`, `method`, and any request `options` you provided in the
    descriptor, such as `options.headers`, during initialization.
  </Step>

  <Step title="Add the access token to the request in your intermediary endpoint">
    The intermediary endpoint receives the encoded request. It must make a
    request to the Qonto proxy endpoint including the access token as the
    `Authorization` header and the payload it receives as the `data` parameter
    in the body.
  </Step>

  <Step title="Get the response from Qonto API and return it to the SDK">
    Once your intermediary endpoint receives the response from the Qonto API, it
    returns it to the SDK without modification and in plain text format.
  </Step>

  <Step title="The SDK returns the response to your app">
    Once the SDK gets the response from your intermediary endpoint, it decodes
    the response and returns it to your application.
  </Step>
</Steps>

# Example Implementation

Let's implement a call to update a SEPA beneficiary using the proxy endpoint.

## Step 1: Create the intermediary endpoint in your backend

We'll assume an application written in TypeScript with Next.js. The intermediary endpoint will be created in the
`/app/api/embed-intermediary.ts` file as a Next Route Handler:

```typescript theme={null}
import { NextRequest } from 'next/server';

const PROXY_ENDPOINT_URL =
  'https://thirdparty.qonto.com/v1/encoded_requests/dispatch';

/**
 * In a real-world scenario, these would not be hardcoded values,
 * and you would store them securely in your backend.
 */
const accessToken = 'your-access-token-here';
const stagingToken = 'your-staging-token-here';

export async function POST(req: NextRequest) {
  const payload = await req.text();
  const options = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Accept: 'application/json',
      /*
       * This is the main purpose of this intermediary endpoint: adding the access token
       * to the request we are making to the Qonto Embed API.
       */
      Authorization: `Bearer ${accessToken}`,
      /**
       * If you are using the staging environment to test your integration, you will also
       * need to provide the staging token obtained from your developer portal account.
       */
      'X-Qonto-Staging-Token': stagingToken,
    },
    /**
     * The Qonto Proxy endpoint expects a JSON body with a `data` field whose value
     * is the base64-encoded string we received
     */
    body: JSON.stringify({ data: payload }),
  };
  try {
    const response = await fetch(PROXY_ENDPOINT_URL, options);
    if (!response.ok) {
      throw new Error(response.statusText);
    }
    const { data } = await response.json();
    /**
     * We return the response from the Qonto Proxy endpoint to our caller without modification.
     */
    return new Response(data, {
      status: 200,
      headers: { 'Content-Type': 'text/plain' },
    });
  } catch {
    return Response.json(
      { error: 'Failed to call the Qonto Proxy endpoint' },
      { status: 500 },
    );
  }
}
```

<Tip>
  The intermediary endpoint needs to be implemented only once and will be used
  for all SDK functions your application calls.
</Tip>

## Step 2: Configure the SDK to call the intermediary endpoint from client-side code

On the client side, configure the SDK to call the intermediary endpoint you just created. Do this by passing the
`proxyEndpointDescriptor` option to the SDK `initialize` function. The descriptor tells the SDK how to reach your
intermediary endpoint — there is no need to write the fetch call yourself:

```typescript theme={null}
import { initialize } from '@qonto/embed-sdk/common';

initialize({
  operationSettings: {
    proxyEndpointDescriptor: {
      // The path to your intermediary endpoint
      path: '/api/embed-intermediary',
      // The HTTP method your intermediary endpoint expects
      method: 'POST',
      options: {
        // Optional headers to include when the SDK calls your endpoint
        headers: {
          'Content-Type': 'text/plain',
        },
      },
    },
  },
});
```

<Tip>
  The `proxyEndpointDescriptor` needs to be configured only once and will be
  used for all SDK functions your application calls.
</Tip>

## Step 3: Call the SDK to update the SEPA beneficiary

Now you can call the SDK to update the SEPA beneficiary. The SDK will prepare the request, encode it, and send it to
your intermediary endpoint. The intermediary endpoint will then add the access token (and staging token) to the request
headers, call the Qonto API, and return the response to the SDK, which will decode it and return it to you.

```typescript theme={null}
import { beneficiaries } from '@qonto/embed-sdk/beneficiaries';

const response = await beneficiaries.updateBeneficiary({
  beneficiaryId: 'beneficiary-id',
  data: {
    name: 'New Name',
    email: 'the-new-email@example.com',
  },
});

console.log('Beneficiary updated:', response);
```

# Conclusion

By following these steps, you have successfully implemented a proxy endpoint that allows you to securely interact with
the Qonto API without exposing your access token to client-side code. This approach ensures that sensitive information
remains protected while still enabling the functionality you need in your application.
