# escher-request

> make and validate escher authenticated http calls

Latest version **1.3.13** (published 2026-07-03) · ISC license · 545 weekly downloads

## Install

```sh
npm install escher-request
pnpm add escher-request
yarn add escher-request
bun add escher-request
```

## Health

**Score 65/100 (B)** — status: active.

Positive: has types; no vulnerabilities; recently updated; high maintenance score; high quality score.

Warnings: low downloads; no esm support.

## Facts

| | |
|---|---|
| Version | 1.3.13 |
| Published | 2026-07-03 |
| First published | 2019-06-16 |
| Weekly downloads | 545 |
| License | ISC |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 3 |
| Unpacked size | 27.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 2 |
| Author | mkls |
| Maintainers | rgargya, mkls, cztamas, akapa, czeildi |
| Keywords | escher, request, auth |

## Links

- npm: https://www.npmjs.com/package/escher-request
- Repository: https://github.com/mkls/escher-request
- Homepage: https://github.com/mkls/escher-request#readme
- Issues: https://github.com/mkls/escher-request/issues
- npm.io page: https://npm.io/package/escher-request

## Dependencies (3)

- [axios](https://npm.io/package/axios.md) 1.18.1
- [lodash](https://npm.io/package/lodash.md) ^4.18.1
- [escher-auth](https://npm.io/package/escher-auth.md) ^4.0.3

## Alternatives

- [@clerk/clerk-expo](https://npm.io/package/@clerk/clerk-expo.md) — 133.6K weekly downloads
- [@pothos/plugin-authz](https://npm.io/package/@pothos/plugin-authz.md) — 12.4K weekly downloads
- [@bounded-sh/client](https://npm.io/package/@bounded-sh/client.md) — 3.2K weekly downloads
- [@luigi-project/plugin-auth-oauth2](https://npm.io/package/@luigi-project/plugin-auth-oauth2.md) — 2.3K weekly downloads
- [@nocobase/plugin-verification](https://npm.io/package/@nocobase/plugin-verification.md) — 2.0K weekly downloads

## Recent versions

- 1.3.13 (latest) — 2026-07-03
- 1.3.12 — 2026-06-03
- 1.3.11 — 2026-04-23
- 1.3.10 — 2026-02-16
- 1.3.9 — 2025-09-15
- 1.3.8 — 2025-08-04
- 1.3.7 — 2025-05-30
- 1.3.6 — 2025-05-30
- 1.3.5 — 2025-05-30
- 1.3.4 — 2025-05-15
- 1.3.3 — 2025-04-17
- 1.3.1 — 2024-01-22
- 1.3.0 — 2023-11-02
- 1.2.2 — 2022-05-19
- 1.2.1 — 2022-02-03
- … 15 more at https://npm.io/package/escher-request/versions

## README

# escher-request

We wanted to make it easier to work with escher requests.
This package provides an alternative to using packages like `escher-suiteapi-js`, `escher-auth`, `escher-keypool` and `koa-escher-auth`.

## Setup

For `escher-request` to work, you should set `ESCHER_INTEGRATIONS` environment
variable set with all your escher related config.

For compatibility reasons `ESCHER_KEY_POOL` and `SUITE_ESCHER_KEY_POOL` variables are also supported
for storing config.

```js
process.env.ESCHER_INTEGRATIONS = `[
  {
    "keyId": "test_test-sender_v1",
    "secret": "code"
  }
  {
    "keyId": "test_test-target_v1",
    "secret": "secret",
    "serviceUrl": "http://www.example.com:8080",
    "credentialScope": "eu/test-target/ems_request"
  }
]`;
```

For each service you want to communicate with include an object in the array with these params:
- `keyId` sent with outgoing request, used during authentication to look up the matching secret
- `secret` used to generate and validate the signature
- `serviceUrl` _(optional)_ base url of the service (needed for outgoing requests)
- `credentialScope` _(optional)_ will be set in auth header when sending a request towards the service (needed for outgoing requests)
- `acceptOnly` _(optional, default `false`)_ makes it easier to rotate your keys. When it's `true` it will only
be used to validate incoming requests, and you can have a second entry for this service with
the new `secret`, version two (`..._v2`) key id and `acceptOnly` as `false` which will be used for outgoing ones.

## API

### Making a request

Request API is intended to be as close to [axios](https://github.com/axios/axios) API as possible.

```js
// Send a POST request
escherRequest.request({
  method: 'post',
  url: 'http://somewhere.com/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
})
```

The main difference is that only absolute url work, as the origin part of the url will be used
to look up the escher `keyId` and `secret` set up in `ESCHER_INTEGRATIONS` for signing the request.

There is also an extra `escherKeyId` option, which lets you make calls with relative urls.
In this case this `keyId` will be used to look up the `serviceUrl` of the target which will
be prepended to the url.

```js
escherRequest.get('/hello', { escherKeyId: 'test_test-target' })
```

Omit version information from the end of the key for this config (eg: `key` instead of `key_v1`)).

This allows you to write environment independent code more easily.
You only have to change the value of the `ESCHER_INTEGRATIONS` environment variable
between environments, and your requests will go to the correct destination signed with
the correct credentials.

If you would like to use the package without `ESCHER_INTEGRATIONS` environment variable, you can
explicitly pass in `escherCredentialScope` and `escherSecret` in config, which will be used
to generate the authentication headers. For this special use case version information have to
be included in the key, and only absolute url can be used.

```js
escherRequest.get('http://localhost:45345/hello', {
  escherKeyId: 'test_test-target_v1',
  escherCredentialScope: 'eu/hap/ems_request',
  escherSecret: 'secret'
});
```

The plan is to support most of axios's config options. `url`, `method`, `headers`, `data`,
`params` and `paramsSerializer` options are pre-processed, since they have direct impact
on the escher signature to be generated. All other options are passed down to axios unchanged.

One noticeable difference from the default options of `axios` is the default value for
`timeout` option. It is 25052 ms, while in `axios` it is 0 (no timeout).

#### Request method aliases
- escherRequest.get(url[, config])
- escherRequest.delete(url[, config])
- escherRequest.head(url[, config])
- escherRequest.options(url[, config])
- escherRequest.post(url[, data[, config]])
- escherRequest.put(url[, data[, config]])
- escherRequest.patch(url[, data[, config]])


### Pre-signing an URL

Pre-signs an url with given expiration (in second, by default it is 86400 secs, aka 24 hours).
Mostly useful for ui handshake requests or integrating an iframe into a front-end.

```js
escherRequest.preSignUrl(
  'http://www.example.com/etwas?a=4',
  { expires: 300 }
)
```

```js
escherRequest.preSignUrl(
  '/etwas?a=4',
  { expires: 300, escherKeyId: 'test_test-target' }
)
```

### Authenticate

When passed in the credentialScope of the service and parameters of a received request, returns
whether it passes authentication or not (correct `credentialScope`, `keyId`, `secret`, etc is used).

```js
const { authenticated, message } = escherRequest.authenticate(
  'eu/test-target/ems_request',
  {
    method: 'POST',
    url: '/puty',
    headers: {
      'content-type': 'application/json',
      host: 'localhost:9193',
      'x-ems-date': '20190616T183748Z',
      'x-ems-auth': 'EMS-HMAC-SHA256 Credential=test_test-target_v1 ...'
    },
    body: '{"duckling":4}'
  }
)
```

`autheticated` is boolean, shows whether it passed authentication or not, `message`
contains a reason if it did not.

Usually you want to wrap this method in a middleware that handles the specifics of your
favorite framework.

See examples for ideas how this could be done: [koa](examples/koa.js),
[koa-with-badyparser](examples/koa-with-bodyparser.js), [express](examples/express.js), [express-with-bodyparser](examples/express-with-bodyparser.js)

## Contributing

This package is currently maintained by @mkls. Feel free to reach out with problems, suggestions
or anything through github issues.

Pull requests are always welcome, just follow our ordinal commit message convention.

Creating a new release:
- make your changes
- update version information in package.json
- document what was changed in CHANGELOG.md
- run `npm publish`

---
_Source: https://npm.io/package/escher-request · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
