Skip to main content
Safepay issues an aggregator secret key ({{secret_key}}) after approving your account. All API requests must include it in the X-SFPY-AGGREGATOR-SECRET-KEY header.

Key format

sk_live_c66a5b38-0ce1-4f83-8d72-57b8f91a8762

Best practices

1

Store in a secret manager

Use AWS Secrets Manager, HashiCorp Vault, or your platform’s equivalent. Restrict read permissions to the services that call Safepay.
2

Rotate regularly

Rotate keys every 90 days or sooner when staff changes. You can create overlapping keys to achieve zero-downtime rotation.
3

Separate by workload

Issue unique keys for payouts vs pay-ins so you can revoke one without disrupting the other.

Create or rotate keys via API

Use the Access Keys API to automate issuance. Set {{base_url}} to https://dev.api.getsafepay.com/raastwire in Sandbox or https://api.getsafepay.com/raastwire in Production.
curl --request POST "{{base_url}}/v1/aggregators/{{aggregator_id}}/keys" \
  --header "X-SFPY-AGGREGATOR-SECRET-KEY: {{secret_key}}" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "payouts-service",
    "is_active": true
  }'
const baseUrl = '{{base_url}}';
const aggregatorId = '{{aggregator_id}}';
const secretKey = process.env.SAFEPAY_SECRET_KEY ?? '';

type CreateAccessKeyPayload = {
  api_version: string;
  data: {
    token: string;
    secret: string;
    name: string;
    is_active: boolean;
  };
};

const res = await fetch(
  `${baseUrl}/v1/aggregators/${aggregatorId}/keys`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-SFPY-AGGREGATOR-SECRET-KEY': secretKey,
    },
    body: JSON.stringify({
      name: 'payouts-service',
      is_active: true,
    }),
  },
);

if (!res.ok) {
  throw new Error(`Key creation failed: ${res.status}`);
}

const payload: CreateAccessKeyPayload = await res.json();
const accessKey = payload.data.token;
const secretKey = payload.data.secret;

Rotate an access key

Use rotation to issue a new secret without changing the access key token.
curl --request PUT "{{base_url}}/v1/aggregators/{{aggregator_id}}/keys/{{access_key_id}}/rotate" \
  --header "X-SFPY-AGGREGATOR-SECRET-KEY: {{secret_key}}"
const baseUrl = '{{base_url}}';
const aggregatorId = '{{aggregator_id}}';
const accessKeyId = '{{access_key_id}}';
const secretKey = process.env.SAFEPAY_SECRET_KEY ?? '';

const res = await fetch(
  `${baseUrl}/v1/aggregators/${aggregatorId}/keys/${accessKeyId}/rotate`,
  {
    method: 'PUT',
    headers: {
      'X-SFPY-AGGREGATOR-SECRET-KEY': secretKey,
    },
  },
);

if (!res.ok) {
  throw new Error(`Key rotation failed: ${res.status}`);
}

List, update, and revoke keys

Always revoke compromised keys immediately using Delete access key and issue replacements.

Header usage reminder

X-SFPY-AGGREGATOR-SECRET-KEY: {{secret_key}}

See also