Skip to main content
Version: 2019-05-29 (Current)

Authentication

Omise uses HTTP Basic Authentication with API keys. Learn how to securely authenticate your requests and choose the right key for each operation.

Overviewโ€‹

Every Omise API request must be authenticated using one of your API keys. Omise provides different key types for different purposes, each with specific access permissions and security requirements.

Quick Start
  • Public Key (pkey_*) โ†’ Client-side code, creates tokens/sources only
  • Secret Key (skey_*) โ†’ Server-side code, full API access
  • Never expose your secret key in client-side code or public repositories

API Keysโ€‹

Key Typesโ€‹

Omise provides three types of API keys:

Key TypeFormatUsed ForWhere to UseAccess Level
Public Keypkey_test_* / pkey_live_*Tokenizing cards, creating sourcesClient-side (browser, mobile app)Limited - can only create tokens & sources
Secret Keyskey_test_* / skey_live_*Charges, customers, refunds, all operationsServer-side onlyFull API access
Chain Keychain_*Parent account operations on sub-merchantsServer-side onlySub-merchant management

Test vs Live Keysโ€‹

Each key type comes in test and live versions:

Test Keys (Development)โ€‹

  • Contain _test_ in the key string
  • Example: skey_test_5xuy4w91xqz7d1w9u0t
  • โœ… Safe for development and testing
  • โœ… Accept test card numbers
  • โœ… Don't process real money
  • โœ… Trigger test webhooks

Live Keys (Production)โ€‹

  • Don't contain _test_
  • Example: skey_live_5xuy4w91xqz7d1w9u0t
  • โš ๏ธ Process real payments
  • โš ๏ธ Charge real cards
  • โš ๏ธ Must be kept secure
Security Critical

Never commit live keys to version control. Use environment variables and secure secret management systems.


Finding Your API Keysโ€‹

  1. Log in to the Omise Dashboard
  2. Navigate to Settings โ†’ Keys
  3. Copy your test keys for development
  4. Copy your live keys when ready for production

You can generate new keys and revoke compromised keys from this page.


How Authentication Worksโ€‹

Omise uses HTTP Basic Authentication:

  • Username: Your API key
  • Password: Leave blank (empty string)

The API key is sent in the Authorization header as a Base64-encoded string:

Authorization: Basic <base64(api_key:)>
Note the Colon

The API key must be followed by a colon (:) when encoding, even though the password is empty.


Authentication Examplesโ€‹

Using cURLโ€‹

# Using secret key
curl https://api.omise.co/account \
-u skey_test_5xuy4w91xqz7d1w9u0t:

# Using public key
curl https://vault.omise.co/tokens \
-X POST \
-u pkey_test_5xuy4w91xqz7d1w9u0t: \
-d "card[name]=John Doe" \
-d "card[number]=4242424242424242" \
-d "card[expiration_month]=12" \
-d "card[expiration_year]=2027" \
-d "card[security_code]=123"

Using Rubyโ€‹

require 'omise'

# Set your secret key
Omise.api_key = 'skey_test_5xuy4w91xqz7d1w9u0t'

# Make authenticated requests
account = Omise::Account.retrieve

# Using public key for tokens
Omise.vault_api_key = 'pkey_test_5xuy4w91xqz7d1w9u0t'
token = Omise::Token.create({
card: {
name: 'John Doe',
number: '4242424242424242',
expiration_month: 12,
expiration_year: 2027,
security_code: '123'
}
})

Using Pythonโ€‹

import omise

# Set your secret key
omise.api_secret = 'skey_test_5xuy4w91xqz7d1w9u0t'

# Make authenticated requests
account = omise.Account.retrieve()

# Using public key for tokens
omise.api_public = 'pkey_test_5xuy4w91xqz7d1w9u0t'
token = omise.Token.create(
name='John Doe',
number='4242424242424242',
expiration_month=12,
expiration_year=2027,
security_code='123'
)

Using PHPโ€‹

<?php
require_once 'vendor/autoload.php';

// Set your secret key
define('OMISE_SECRET_KEY', 'skey_test_5xuy4w91xqz7d1w9u0t');
define('OMISE_PUBLIC_KEY', 'pkey_test_5xuy4w91xqz7d1w9u0t');

// Make authenticated requests
$account = OmiseAccount::retrieve();

// Using public key for tokens
$token = OmiseToken::create(array(
'card' => array(
'name' => 'John Doe',
'number' => '4242424242424242',
'expiration_month' => 12,
'expiration_year' => 2027,
'security_code' => '123'
)
));

Using Node.jsโ€‹

const omise = require('omise')({
secretKey: 'skey_test_5xuy4w91xqz7d1w9u0t',
publicKey: 'pkey_test_5xuy4w91xqz7d1w9u0t'
});

// Make authenticated requests
const account = await omise.account.retrieve();

// Using public key for tokens
const token = await omise.tokens.create({
card: {
name: 'John Doe',
number: '4242424242424242',
expiration_month: 12,
expiration_year: 2027,
security_code: '123'
}
});

Using Goโ€‹

package main

import (
"github.com/omise/omise-go"
"github.com/omise/omise-go/operations"
)

func main() {
client, _ := omise.NewClient(
"pkey_test_5xuy4w91xqz7d1w9u0t",
"skey_test_5xuy4w91xqz7d1w9u0t",
)

// Make authenticated requests
account, _ := client.Account()

// Using public key for tokens
token, _ := client.CreateToken(&operations.CreateToken{
Name: "John Doe",
Number: "4242424242424242",
ExpirationMonth: 12,
ExpirationYear: 2027,
SecurityCode: "123",
})
}

Which Key to Useโ€‹

Use Public Key For:โ€‹

โœ… Client-Side Operations (Browser, Mobile App)

  • Creating tokens from card data
  • Creating sources for alternative payment methods
  • Any operation that handles sensitive card information

Why? The public key is safe to embed in client-side code because it can only create tokens and sources - it cannot charge cards or access sensitive account data.

// โœ… Safe - Public key in client-side JavaScript
Omise.setPublicKey('pkey_test_5xuy4w91xqz7d1w9u0t');
Omise.createToken('card', cardData, function(status, response) {
// Send token to server
});

Use Secret Key For:โ€‹

โœ… Server-Side Operations Only

  • Creating charges
  • Managing customers
  • Processing refunds
  • Creating transfers
  • Accessing account information
  • Any operation involving money or sensitive data

Why? The secret key has full API access and must never be exposed.

# โœ… Safe - Secret key on server only
Omise.api_key = ENV['OMISE_SECRET_KEY']
charge = Omise::Charge.create({
amount: 100000,
currency: 'thb',
card: params[:omise_token]
})

โŒ Never Do This:โ€‹

<!-- โŒ DANGEROUS - Secret key exposed in HTML -->
<script>
const secretKey = 'skey_live_5xuy4w91xqz7d1w9u0t';
</script>
// โŒ DANGEROUS - Secret key in client-side code
fetch('https://api.omise.co/charges', {
headers: {
'Authorization': 'Basic ' + btoa('skey_live_...:')
}
});

Security Best Practicesโ€‹

1. Store Keys Securelyโ€‹

โœ… Good: Environment Variablesโ€‹

# .env file (DO NOT commit to git)
OMISE_PUBLIC_KEY=pkey_test_5xuy4w91xqz7d1w9u0t
OMISE_SECRET_KEY=skey_test_5xuy4w91xqz7d1w9u0t
# Access in your code
Omise.api_key = ENV['OMISE_SECRET_KEY']

โœ… Good: Secret Management Systemsโ€‹

  • AWS Secrets Manager
  • Google Cloud Secret Manager
  • Azure Key Vault
  • HashiCorp Vault

โŒ Bad: Hardcoded Keysโ€‹

# โŒ NEVER hardcode keys
Omise.api_key = 'skey_test_5xuy4w91xqz7d1w9u0t'

2. Separate Test and Productionโ€‹

# Development environment
OMISE_SECRET_KEY=skey_test_...

# Production environment
OMISE_SECRET_KEY=skey_live_...

3. Rotate Keys Regularlyโ€‹

If you suspect a key has been compromised:

  1. Generate a new key in the Dashboard
  2. Update your application with the new key
  3. Test thoroughly
  4. Revoke the old key

4. Restrict Key Permissionsโ€‹

While Omise doesn't support granular key permissions yet, follow the principle of least privilege:

  • Use public keys wherever possible
  • Keep secret keys on secure servers only
  • Never share keys between team members (each should have their own dashboard account)

5. Monitor Key Usageโ€‹

  • Check Dashboard logs regularly
  • Set up alerts for unusual activity
  • Monitor failed authentication attempts

Authentication Errorsโ€‹

401 Unauthorizedโ€‹

Cause: Invalid or missing API key

{
"object": "error",
"code": "authentication_failure",
"message": "authentication failed"
}

Solutions:

  • โœ… Check that your API key is correct
  • โœ… Ensure the key hasn't been revoked
  • โœ… Verify you're using the right key for the operation
  • โœ… Check for extra spaces or characters in the key

403 Forbiddenโ€‹

Cause: Key is valid but lacks permission for this operation

{
"object": "error",
"code": "forbidden",
"message": "key has insufficient permissions"
}

Solutions:

  • โœ… Use secret key instead of public key
  • โœ… Check if your account has access to this feature
  • โœ… Verify key hasn't been restricted

API Versioningโ€‹

Specify the API version in requests using the Omise-Version header:

curl https://api.omise.co/charges \
-u skey_test_5xuy4w91xqz7d1w9u0t: \
-H "Omise-Version: 2019-05-29"

If not specified, requests use your account's default API version (set in Dashboard).

Learn more about API Versioning โ†’


Testing Authenticationโ€‹

Test with Account Endpointโ€‹

The simplest way to test your authentication:

# Test secret key
curl https://api.omise.co/account \
-u skey_test_5xuy4w91xqz7d1w9u0t:

# Test public key (should fail - public keys can't access /account)
curl https://api.omise.co/account \
-u pkey_test_5xuy4w91xqz7d1w9u0t:

Expected Response (Secret Key):

{
"object": "account",
"id": "acct_5xuy4w91xqz7d1w9u0t",
"email": "merchant@example.com",
"created_at": "2027-01-01T00:00:00Z",
...
}

Expected Response (Public Key):

{
"object": "error",
"code": "authentication_failure",
"message": "authentication failed"
}

FAQโ€‹

Can I use the same key for multiple applications?

Yes, but it's not recommended for production. While technically possible, using separate keys for different applications helps with:

  • Security (revoke one key without affecting others)
  • Monitoring (track usage per application)
  • Debugging (identify which app has issues)

Consider using sub-merchant accounts for completely separate applications.

What happens if my secret key is compromised?
  1. Immediately generate a new secret key in the Dashboard
  2. Update your application with the new key
  3. Revoke the compromised key
  4. Monitor your account for unauthorized charges
  5. Contact support@omise.co if you see suspicious activity
Can I regenerate keys without downtime?

Yes! Omise allows you to have multiple active keys simultaneously:

  1. Generate a new key
  2. Deploy your application with the new key
  3. Verify the new key works
  4. Revoke the old key

This allows zero-downtime key rotation.

Do API keys expire?

No, Omise API keys don't expire automatically. However, you should:

  • Rotate keys regularly (every 6-12 months)
  • Revoke unused keys
  • Generate new keys after team member departures
Can I restrict API key permissions?

Currently, Omise has two permission levels:

  • Public keys - Limited to token/source creation
  • Secret keys - Full API access

Granular permission controls are not yet available. Use separate sub-merchant accounts for isolation.


Quick Referenceโ€‹

Authentication Checklistโ€‹

Before going live, verify:

  • Secret key stored in environment variables
  • Public key used for client-side token creation
  • No keys hardcoded in application code
  • No keys committed to version control
  • Test keys used in development/staging
  • Live keys used in production only
  • Keys secured with proper file permissions
  • Team members use individual dashboard accounts
  • Key rotation plan in place
  • Monitoring set up for authentication failures

Key Format Referenceโ€‹

Public Test:    pkey_test_XXXXXXXXXXXXXXXXXXXX
Public Live: pkey_live_XXXXXXXXXXXXXXXXXXXX
Secret Test: skey_test_XXXXXXXXXXXXXXXXXXXX
Secret Live: skey_live_XXXXXXXXXXXXXXXXXXXX
Chain: chain_XXXXXXXXXXXXXXXXXXXX


Next: Learn about Error Handling to gracefully handle API failures.