Get card BIN


The BIN Info endpoint provides card metadata based on Bank Identification Numbers (BINs) from DEUNA's internal catalog. This endpoint is designed to support promotional logic that depends on card characteristics such as franchise, issuing bank, and card type.

Endpoint Details:

Base URL: /v1/cards/bin/{bin} Method: GET Authentication: API Key required

Request Format

URL Parameters

ParameterTypeRequiredDescription
binStringYesExactly 6 numeric digits (e.g., "123456")

Headers

Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Example Request

GET /v1/cards/bin/123456 HTTP/1.1
Host: api.deuna.com
Authorization: Bearer your_api_key_here
Content-Type: application/json

Response Format

Successful Response (200 OK)

{
  "bin": "123456",
  "franchise": "VISA",
  "issuer_bank": "Chase Bank",
  "card_type": "CREDIT"
}

Response Fields

FieldTypeDescriptionPossible Values
binStringThe 6-digit BIN that was queried6-digit numeric string
franchiseStringCard network/brandVISA, MASTERCARD, AMEX, DISCOVER, OTROS
issuer_bankStringName of the issuing bankHuman-readable bank name (e.g., "BBVA", "Bancolombia", "Chase Bank")
card_typeStringType of cardCREDIT, DEBIT, PREPAID, UNKNOWN

Error Responses

400 Bad Request - Invalid BIN Format

{
  "error": "BAD_REQUEST",
  "message": "BIN must be exactly 6 numeric digits",
  "code": "INVALID_BIN_FORMAT"
}

Causes:

  • BIN is not exactly 6 digits
  • BIN contains non-numeric characters
  • BIN is missing or empty

401 Unauthorized

{
  "error": "UNAUTHORIZED",
  "message": "Invalid or missing API key",
  "code": "AUTH_ERROR"
}

404 Not Found - BIN Not in Catalog

{
  "error": "NOT_FOUND",
  "message": "BIN not found in catalog",
  "code": "BIN_NOT_FOUND"
}

429 Too Many Requests - Rate Limit Exceeded

{
  "error": "TOO_MANY_REQUESTS",
  "message": "Rate limit exceeded",
  "code": "RATE_LIMIT_EXCEEDED"
}

Usage Examples

Example 1: Valid BIN Query

Request:

curl -X GET "https://api.deuna.com/v1/cards/bin/411111" \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json"

Response:

{
  "bin": "411111",
  "franchise": "VISA",
  "issuer_bank": "Chase Bank",
  "card_type": "CREDIT"
}

Example 2: BIN Not Found

Request:

curl -X GET "https://api.deuna.com/v1/cards/bin/999999" \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json"

Response (404):

{
  "error": "NOT_FOUND",
  "message": "BIN not found in catalog",
  "code": "BIN_NOT_FOUND"
}

Example 3: Invalid BIN Format

Request:

curl -X GET "https://api.deuna.com/v1/cards/bin/12345" \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json"

Response (400):

{
  "error": "BAD_REQUEST",
  "message": "BIN must be exactly 6 numeric digits",
  "code": "INVALID_BIN_FORMAT"
}

Implementation Guidelines

Input Validation

Before making requests, ensure your BIN meets these criteria:

  • Exactly 6 characters long
  • Contains only numeric digits (0-9)
  • Leading zeros are acceptable
function isValidBIN(bin) {
  return /^[0-9]{6}$/.test(bin);
}

Error Handling

Always implement proper error handling for all possible response codes:

async function getBINInfo(bin) {
  if (!isValidBIN(bin)) {
    throw new Error('Invalid BIN format');
  }
  
  try {
    const response = await fetch(`/v1/cards/bin/${bin}`, {
      headers: {
        'Authorization': 'Bearer ' + apiKey,
        'Content-Type': 'application/json'
      }
    });
    
    if (response.status === 200) {
      return await response.json();
    } else if (response.status === 404) {
      throw new Error('BIN not found');
    } else if (response.status === 429) {
      throw new Error('Rate limit exceeded');
    } else {
      throw new Error('Unexpected error');
    }
  } catch (error) {
    console.error('BIN lookup failed:', error);
    throw error;
  }
}

Rate Limiting

  • Default limit: 1000 requests per minute per API key
  • Monitor your usage to avoid hitting rate limits
  • Implement exponential backoff for retry logic

Caching Recommendations

Since BIN data is relatively stable:

  • Consider caching successful responses locally
  • Cache duration: 24-48 hours recommended
  • Always respect cache-control headers if provided

Use Cases

Promotional Logic

Use the endpoint to determine card eligibility for promotions:

async function checkPromoEligibility(bin) {
  try {
    const cardInfo = await getBINInfo(bin);
    
    // Example: 10% off for VISA credit cards from specific banks
    if (cardInfo.franchise === 'VISA' && 
        cardInfo.card_type === 'CREDIT' && 
        ['Chase Bank', 'Bank of America'].includes(cardInfo.issuer_bank)) {
      return { eligible: true, discount: 0.10 };
    }
    
    return { eligible: false };
  } catch (error) {
    // Handle BIN not found or other errors
    return { eligible: false, error: error.message };
  }
}

Card Type Detection

Use the endpoint to determine the brand and type of a card:

async function getCardType(bin) {
  try {
    const cardInfo = await getBINInfo(bin);
    return {
      type: cardInfo.card_type,
      franchise: cardInfo.franchise,
      bank: cardInfo.issuer_bank
    };
  } catch (error) {
    return { type: 'UNKNOWN', error: error.message };
  }
}