Source: https://cryptanio.com/wiki/api-key-single-project/
Language: en

# How to restrict an API key to one project

Create a separate key for server\-side invoice reconciliation in one project\: select the project\, read access and the required API section\, configure IP rules and expiry\, then test the access boundary\.

Updated: 2026-11-14

An API key can be bound to a single Cryptanio project\. This guide uses an order\-reconciliation process that needs to read an online shop\'s [invoices](<https://cryptanio.com/wiki/what-is-an-invoice/>) without accessing data from the account\'s other projects\. It needs a separate key\: the project binding defines the data boundary\, while permissions and API sections define the allowed operations\.

Neither the key\'s label nor a project number in your application restricts access on its own\. You must save the restriction in the key\'s policy\. The access applies to the public API v1\; the key is not a password for signing in to the dashboard\.

## 1\. Prepare the project and permissions {#1-prepare-the-project-and-permissions}

You need account owner or administrator permissions and an existing active project with the Payments service\. First make sure you understand its name and purpose\: choosing the wrong project can produce a valid key with the wrong access boundary\.

Open API keys\. In the Create API key form\, set Label\, for example “Shop reconciliation”\. A separate label helps distinguish server processes\, but the actual protection is configured in the following fields\.

## 2\. Select the mode and a specific project {#2-select-the-mode-and-a-specific-project}

To read real invoices\, choose Live in Mode\. The key must match the mode of the data your server requests\.

In Project\, select the required project instead of All projects\. The dashboard shows a hint about the restriction to the selected project\'s service\. Project binding and service access apply together\: the key does not activate the service or extend its capabilities on its own\.

## 3\. Keep only invoice read access {#3-keep-only-invoice-read-access}

In Access\, select Read only\. Under API sections\, keep Invoices and clear the other checkboxes if the process does not need them\. Ordinary invoice\-status reconciliation does not require managing addresses\, webhooks or simulation\.

If another server needs to create invoices\, it will need Read and write and the corresponding section\. Give it a separate key with a clear purpose\, rather than unnecessarily expanding the reconciliation process\'s permissions\. Write access applies within the selected sections\, not to the entire API\.

## 4\. Configure IP rules and expiry {#4-configure-ip-rules-and-expiry}

In Allowed IP addresses\, enter your server\'s public outbound IP addresses or the necessary CIDR ranges\, one per line\. Use the address from which the request reaches the API\, not the buyer\'s IP\. If you use hosting or a proxy\, establish the actual outbound address\.

An empty field permits any IP\. If the server uses several outbound addresses\, account for them in the configuration\; otherwise a valid key may fail the check\. IP restrictions supplement the project and section selections rather than replacing them\.

Set Expires if needed\. The selected date is valid until the end of that day in UTC\. Align it with your integration\'s operating period\: an expired key is not a sign that a customer has not paid\.

## 5\. Create the key and save the secret {#5-create-the-key-and-save-the-secret}

Click Create key and complete the security confirmation if the dashboard requests it\. Copy the secret from the displayed window and store it on the reconciliation server\. Do not place it in client\-side JavaScript\, a payment link\, correspondence with the buyer or public logs\.

After closing the window\, do not expect to recover the secret from the list\: it shows an abbreviated key identifier\. Check Boundary\, the project\, available sections\, expiry and status\. If a developer needs access\, share it through a suitable secure store rather than publishing the key alongside the instructions\.

## 6\. Test allowed and denied access {#6-test-allowed-and-denied-access}

From a server with an allowed IP\, read a known invoice in this project\. Below is a read example from the API catalogue\; use your own invoice ID and the key you created\:

```bash
#!/usr/bin/env bash
set -euo pipefail
: "${CRYPTANIO_RESOURCE_ID:?Set CRYPTANIO_RESOURCE_ID}"
: "${CRYPTANIO_API_KEY:?Set CRYPTANIO_API_KEY}"
urlencode() {
  local LC_ALL=C text="$1" char index
  for ((index=0; index<${#text}; index++)); do
    char="${text:index:1}"
    case "$char" in [a-zA-Z0-9.~_-]) printf '%s' "$char" ;; *) printf '%%%02X' "'$char" ;; esac
  done
}
response_file="$(mktemp)"
trap 'rm -f "$response_file"' EXIT
transfer_status=0
http_status="$(curl \
  --silent --show-error --max-time 30 --request GET \
  --header "Authorization: Bearer $CRYPTANIO_API_KEY" \
  --header 'Accept: application/json' \
  "https://api.cryptanio.com/v1/invoices/$(urlencode "$CRYPTANIO_RESOURCE_ID")" \
  --output "$response_file" --write-out '%{http_code}')" || transfer_status=$?
if [[ "$http_status" == 2?? ]]; then
  cat "$response_file"
  exit "$transfer_status"
fi
printf 'HTTP %s\n' "$http_status" >&2
cat "$response_file" >&2
exit 1
```

[Download example](</wiki/examples/ae4ad34d7f9814c6019ca3494a7e6c605b0f2488e3bd223a4a4ce34ae8c220da.sh>)

Then test the boundary with a known invoice from another of your projects\: its data must not be returned\. Lists must also remain within the selected project\. This key cannot create or modify invoices\, even when Invoices is enabled\. Further reconciliation is covered in the [guide to checking payment through the API](<https://cryptanio.com/wiki/check-payment-api-without-webhook/>)\.

If a request fails\, check the project\, mode\, IP\, expiry and permissions\. Do not conclude that payment is missing from one access error\, and do not substitute an account\-wide key for the restricted key\. Payment is assessed from the [invoice](<https://cryptanio.com/wiki/what-is-an-invoice/>) state\.

## How to adjust access later {#how-to-adjust-access-later}

For an existing key\, click Access\, change the project\, sections\, IP rules or expiry\, then select Save access\. Mode is selected when creating the key\. Rotate changes the secret and immediately disables the old one\; Revoke stops the key being used\. Prepare updates to server clients before rotating so that order reconciliation does not stop\.

Tags: [Payments](https://cryptanio.com/wiki/tag/payments/), [API](https://cryptanio.com/wiki/tag/api/)

## Related articles

- [What is an invoice](https://cryptanio.com/wiki/what-is-an-invoice/)
- [How to check payment through the API without a webhook](https://cryptanio.com/wiki/check-payment-api-without-webhook/)
- [How to accept USDC payments on your website](https://cryptanio.com/wiki/accept-usdc-payments-website/)
