---
title: "Sign BizPrint Print API requests"
description: "Sign every BizPrint Print API request with your Public Key, the current time and a SHA-256 hash made with your Secret Key."
url: https://docs.getbizprint.com/developers/authentication/
section: "Developers"
last_updated: 2026-11-12
---

# Sign BizPrint Print API requests

Section: Developers

> Sign every BizPrint Print API request with your Public Key, the current time and a SHA-256 hash made with your Secret Key.

This page shows you how to sign requests to the BizPrint Print API, so BizPrint knows they come from your [application](https://docs.getbizprint.com/start-here/glossary/#application). It is for developers calling the API from their own server code.

Your [Secret Key](https://docs.getbizprint.com/start-here/glossary/#public-key-and-secret-key) is never sent. Instead, every request carries three values:

- `publicKey`: your application’s Public Key.
- `time`: the current time as a Unix timestamp in seconds.
- `hash`: a SHA-256 hash, in lowercase hexadecimal, of the request data followed by a colon and your Secret Key.

## Before you start

- Get your application’s Public Key and Secret Key. See [Get API keys for the BizPrint Print API](https://docs.getbizprint.com/developers/get-api-keys/).
- Keep the Secret Key on your server. Sign requests only in server code, never in a web page, browser JavaScript or a mobile app.
- Make sure your server’s clock is set correctly. BizPrint checks the `time` value, so it must be the current time.

All Print API addresses start with this base URL:

```text
https://print.bizswoop.app/api/connect-application/v1
```

## Sign a GET request

For a GET request, the three values go in the query string.

1. Start with the query parameters the request needs, if any, for example `perPage=10&page=1`.
2. Add `publicKey` with your Public Key.
3. Add `time` with the current Unix time in seconds.
4. Take the query string as it will be sent, without the leading `?`. Do not include `hash`.
5. Add a colon and your Secret Key to the end of that string.
6. Make a SHA-256 hash of the result, written as lowercase hexadecimal.
7. Add the hash to the end of the query string as `hash`.
8. Send the request without changing the order or encoding of the other parameters.

The query string you send then looks like this:

```text
perPage=10&page=1&publicKey=YOUR_PUBLIC_KEY&time=1700000000&hash=THE_HASH
```

## Sign a POST request

For a POST request, the three values go in the JSON body.

1. Start with the JSON body the request needs.
2. Add a `publicKey` property with your Public Key.
3. Add a `time` property with the current Unix time in seconds, as a number.
4. Turn the body into compact JSON text, with no spaces or line breaks between values.
5. Add a colon and your Secret Key to the end of that text.
6. Make a SHA-256 hash of the result, written as lowercase hexadecimal.
7. Add the hash to the body as a `hash` property, after all the other properties.
8. Send the body as JSON with the header `Content-Type: application/json`. Keep the properties in the same order you used for the hash.

## Example in Node.js

This example uses Node.js 18 or later. It reads the keys from environment variables, so they never appear in your code.

```js
import { createHash } from 'node:crypto';

const BASE_URL = 'https://print.bizswoop.app/api/connect-application/v1';
const publicKey = process.env.BIZPRINT_PUBLIC_KEY; // YOUR_PUBLIC_KEY
const secretKey = process.env.BIZPRINT_SECRET_KEY; // YOUR_SECRET_KEY, server only

const sha256Hex = (text) => createHash('sha256').update(text).digest('hex');
const now = () => Math.floor(Date.now() / 1000);

// GET: sign the query string.
export async function signedGet(path, params = {}) {
  const query = new URLSearchParams(params);
  query.set('publicKey', publicKey);
  query.set('time', String(now()));
  const hash = sha256Hex(`${query.toString()}:${secretKey}`);
  query.set('hash', hash);

  const response = await fetch(`${BASE_URL}${path}?${query.toString()}`);
  return { status: response.status, body: await response.json() };
}

// POST: sign the JSON body.
export async function signedPost(path, data) {
  const body = { ...data, publicKey, time: now() };
  const hash = sha256Hex(`${JSON.stringify(body)}:${secretKey}`);

  const response = await fetch(`${BASE_URL}${path}`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ ...body, hash }),
  });
  return { status: response.status, body: await response.json() };
}
```

For example, `signedGet('/printers', { perPage: 10, page: 1 })` lists your [printers](https://docs.getbizprint.com/start-here/glossary/#printer).

## Example in PHP

The hash covers the exact JSON text, and BizPrint compares it with JSON written the way JavaScript’s `JSON.stringify` writes it. PHP escapes slashes and non-English characters by default, so turn that off with the `JSON_UNESCAPED_SLASHES` and `JSON_UNESCAPED_UNICODE` flags. Otherwise any body that contains a URL will not match.

```php
<?php
$publicKey = getenv('BIZPRINT_PUBLIC_KEY'); // YOUR_PUBLIC_KEY
$secretKey = getenv('BIZPRINT_SECRET_KEY'); // YOUR_SECRET_KEY, server only
$printerId = 0; // replace 0 with YOUR_PRINTER_ID, as a number
$flags = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE;

$body = [
    'printerId'   => $printerId,
    'url'         => 'https://example.com/receipts/1001.pdf',
    'description' => 'Order 1001',
    'publicKey'   => $publicKey,
    'time'        => time(),
];
$body['hash'] = hash('sha256', json_encode($body, $flags) . ':' . $secretKey);

$json = json_encode($body, $flags);
// Send $json in a POST request with the header Content-Type: application/json.
```

## Check your signature

You can check a signature by hand with the signing tool. It signs a request from your keys, or checks the hash on a request you made. See [Sign and check BizPrint Print API requests with the signing tool](https://docs.getbizprint.com/developers/signing-tool/).

## When signing fails

If BizPrint cannot match the signature, or the `time` value is not current, the request fails with HTTP status 401 and the error code `ERR_UNAUTHORIZED`. Check these things:

- The Public Key and Secret Key come from the same application, and you copied them in full.
- Your server’s clock is correct, and you make a new `time` value for every request.
- For a GET request, you hashed the query string exactly as you sent it, without the `?` and without `hash`.
- For a POST request, you hashed compact JSON, sent the same properties in the same order, and sent `time` as a number.
- You hashed the text, a colon and the Secret Key, in that order, and wrote the hash in lowercase hexadecimal.

For the other error codes, see [BizPrint Print API error codes and how to fix them](https://docs.getbizprint.com/developers/errors/).

## Related pages

- [Get API keys for the BizPrint Print API](https://docs.getbizprint.com/developers/get-api-keys/)
- [Create a print job with the BizPrint Print API](https://docs.getbizprint.com/developers/create-print-job/)
- [Sign and check BizPrint Print API requests with the signing tool](https://docs.getbizprint.com/developers/signing-tool/)
- [BizPrint Print API error codes and how to fix them](https://docs.getbizprint.com/developers/errors/)

Need help? Contact BizPrint support at <https://getbizprint.com/support/>.
