Skip to main content
Complete reference for all classes, methods, and response models in the nekuda SDKs.

NekudaClient

The main client for interacting with the nekuda API. It should be instantiated once and reused. It uses https://api.nekuda.ai as the default base_url.

Constructor

  • Python
  • TypeScript
from nekuda import NekudaClient

client = NekudaClient(
    api_key="sk_live_your_api_key",  # Replace with your actual secret API key
    # base_url="https://api.nekuda.ai",  # Default, usually not needed
    timeout=30,  # Optional: request timeout in seconds
    max_retries=3,  # Optional: max retries for retryable errors (429, 5xx)
    backoff_factor=0.5,  # Optional: backoff factor for retries
)
  • Python
  • TypeScript
api_key
string
required
Your nekuda Secret API key (starts with sk_live_ or sk_test_). Must be provided either directly or via the NEKUDA_API_KEY environment variable.
base_url
string
default:"https://api.nekuda.ai"
The base URL for the nekuda API. Defaults to production. Only change this for staging/testing (e.g., https://staging-api.nekuda.ai) or if using a mock server. The SDK normalizes this URL.
timeout
int
default:"30"
Request timeout in seconds for HTTP calls.
max_retries
int
default:"3"
Maximum number of retry attempts for retryable errors (HTTP 429, 5xx).
backoff_factor
float
default:"0.5"
Multiplier for exponential backoff between retries. sleep = (2 ** (retry_attempt - 1)) * backoff_factor.

Class Methods

from_env() / fromEnv()

Factory method to create a client instance configured from environment variables.
  • Python
  • TypeScript
from nekuda import NekudaClient

# Reads NEKUDA_API_KEY for the API key.
# Reads NEKUDA_BASE_URL (optional) for the base URL, defaults to https://api.nekuda.ai.
# Allows overriding other client parameters too.
client = NekudaClient.from_env(
    # api_key_var="CUSTOM_API_KEY_ENV_VAR_NAME", # Default: "NEKUDA_API_KEY"
    # base_url_var="CUSTOM_BASE_URL_ENV_VAR_NAME", # Default: "NEKUDA_BASE_URL"
    timeout=45 # Example: override default timeout
)
This is the recommended way to initialize the client for most applications.

Instance Methods

Creates a UserContext for a specific user. This context automatically includes the user ID in subsequent API calls made through it. A user ID is a mandatory string that uniquely identifies your end-user.
  • Python
  • TypeScript
from nekuda import NekudaClient

client = NekudaClient.from_env()
user_identifier = "unique_user_abc_123"
user_context = client.user(user_identifier)

# Now use methods on user_context:
# mandate_response = user_context.create_mandate(...)
# reveal_token_response = user_context.request_card_reveal_token(...)
# card_details = user_context.reveal_card_details(...)
Using UserContext is preferred over passing user ID to each client method directly.
Note: It is recommended to use userContext.createMandate(mandateData) instead.Creates a purchase mandate (intent to buy) for a given user. This is a required first step before a card reveal token can be requested.
  • Python
  • TypeScript
from nekuda import NekudaClient, MandateData

client = NekudaClient.from_env()
user_identifier = "user_for_mandate_creation"

mandate_info = MandateData(
    product="Deluxe Widget",
    price=199.99,
    currency="USD",
    merchant="My Test Shop"
)

# Optional idempotency key for safe retries of this specific request
# custom_request_id = "my_unique_mandate_request_001"

try:
    response = client.create_mandate(
        user_id=user_identifier,
        mandate_data=mandate_info,
        # request_id=custom_request_id
    )
    print(f"Mandate Created: {response.mandate_id} for user: {user_identifier}")
    # The response.mandate_id is then used for request_card_reveal_token
except NekudaError as e:
    print(f"Error creating mandate: {e}")
Note: It is recommended to use userContext.requestCardRevealToken(mandateId) instead.Requests a one-time, short-lived token to reveal card details for a specific mandate. A mandate must have been successfully created first to obtain a mandate ID.
  • Python
  • TypeScript
from nekuda import NekudaClient

client = NekudaClient.from_env()
user_identifier = "user_for_token_request"
existing_mandate_id = 12345 # Obtained from a previous create_mandate call

try:
    response = client.request_card_reveal_token(
        user_id=user_identifier,
        mandate_id=existing_mandate_id
    )
    print(f"Reveal Token: {response.token} for user: {user_identifier}")
    # This response.token is then used for reveal_card_details
except NekudaError as e:
    print(f"Error requesting reveal token: {e}")
Note: It is recommended to use userContext.revealCardDetails(revealToken) instead.Reveals actual card details using a valid reveal token.
  • Python
  • TypeScript
from nekuda import NekudaClient

client = NekudaClient.from_env()
user_identifier = "user_for_card_reveal"
valid_reveal_token = "rvl_tok_from_previous_step"

try:
    card = client.reveal_card_details(
        user_id=user_identifier,
        reveal_token=valid_reveal_token
    )
    print(f"Card Number (last 4): {card.card_number[-4:]} for user: {user_identifier}")
    print(f"Card Expiry: {card.card_expiry_date}")
except NekudaError as e:
    print(f"Error revealing card details: {e}")

UserContext

A convenience wrapper returned by client.user(userId) that automatically includes the user ID in all its API calls. This is the recommended way to interact with user-specific endpoints.
  • Python
  • TypeScript
from nekuda import NekudaClient, MandateData

client = NekudaClient.from_env()
user_context = client.user("unique_user_id_789")

# Example mandate creation using UserContext
mandate_details = MandateData(
    product="Super Plan", price=29.00, currency="EUR", merchant="My Service"
)
try:
    mandate_response = user_context.create_mandate(mandate_details)
    print(f"Mandate ID from UserContext: {mandate_response.mandate_id}")

    # Request reveal token using UserContext and the new mandate_id
    reveal_token_response = user_context.request_card_reveal_token(mandate_response.mandate_id)
    print(f"Reveal Token from UserContext: {reveal_token_response.token[:10]}...")

    # Reveal card details using UserContext and the new token
    card_object = user_context.reveal_card_details(reveal_token_response.token)
    print(f"Cardholder via UserContext: {card_object.cardholder_name}")
except NekudaError as e:
    print(f"UserContext operation failed: {e}")
The UserContext object has the following methods:
  • create_mandate(mandate_data: MandateData, request_id: Optional[str] = None) -> MandateCreateResponse
  • request_card_reveal_token(mandate_id: Union[str, int]) -> CardRevealTokenResponse
  • reveal_card_details(reveal_token: str) -> CardDetailsResponse

Data Models

MandateData

Represents the user’s intent to purchase. This data is sent when creating a mandate.
  • Python
  • TypeScript
from nekuda import MandateData, NekudaValidationError

try:
    mandate = MandateData(
        # Required fields
        product="Premium Subscription",     # Name of the product/service
        price=49.99,                       # Price (must be > 0)
        currency="USD",                    # 3-letter ISO currency code

        # Optional fields
        merchant="Your Company LLC",       # Your merchant name displayed to user
        merchant_link="https://yourcompany.com/premium", # Link to product/merchant
        product_description="Monthly access to all premium features and support.",
        confidence_score=0.95,             # Your system's confidence (0.0 to 1.0) that this is a legitimate user intent
        # request_id: Optional[str] = None # Auto-generated UUID if not provided for create_mandate idempotency
    )
except NekudaValidationError as e:
    print(f"Invalid MandateData: {e}")
  • Python
  • TypeScript
product
string
required
Name of the product or service being purchased.
price
float
required
Price of the product. Must be a positive number.
currency
string
required
3-letter ISO currency code (e.g., “USD”, “EUR”).
merchant
string
Name of the merchant or store.
URL related to the merchant or product.
product_description
string
A more detailed description of the product or service.
confidence_score
float
A score (0.0 to 1.0) indicating your system’s confidence in this purchase intent.
request_id
Optional[str]
An optional idempotency key for the create_mandate call. If not provided, the SDK generates one.

Response Models

All SDK API methods return typed models with automatic validation.
  • MandateCreateResponse
  • CardRevealTokenResponse
  • CardDetailsResponse
Response from mandate creation.
  • Python
  • TypeScript
class MandateCreateResponse:
    mandate_id: int                    # Unique ID for the created mandate
    request_id: str                    # Request tracking ID (idempotency key used or generated)
    customer_id: str                   # The user_id you provided for this mandate
    created_at: datetime               # Timestamp of mandate creation (UTC)
    updated_at: Optional[datetime]     # Timestamp of last update (UTC), if any
Example Usage:
# mandate_resp = user_context.create_mandate(...)
# print(f"New Mandate ID: {mandate_resp.mandate_id}")
# print(f"Associated User (Customer ID): {mandate_resp.customer_id}")

Exceptions

All exceptions raised by the SDKs inherit from a base NekudaError class. Refer to the Error Handling guide for a detailed hierarchy and usage patterns.

Key Exception Classes

  • Python
  • TypeScript
  • NekudaError (Base class)
  • NekudaApiError (Base for API-returned errors)
    • AuthenticationError (401 - Invalid API key)
    • InvalidRequestError (4xx - e.g., bad parameters, resource not found)
      • CardNotFoundError (Specific 404 for card not found)
    • RateLimitError (429 - Rate limit exceeded, SDK retries these)
    • ServerError (5xx - Server-side issue at nekuda, SDK retries these)
  • NekudaConnectionError (Network issues like DNS or TCP errors)
  • NekudaValidationError (Client-side or response data validation failure against Pydantic models)

Common Exception Attributes

  • Python
  • TypeScript
message
str
Human-readable error message.
code
Optional[str]
A machine-readable error code string from the API, if available (e.g., invalid_api_key, mandate_not_found).
status_code
Optional[int]
The HTTP status code returned by the API (e.g., 401, 404, 500).

Usage Examples

This example shows the end-to-end flow: creating a client, getting a user context, creating a mandate, requesting a reveal token, and revealing card details.
  • Python
  • TypeScript
from nekuda import NekudaClient, MandateData, NekudaError, CardNotFoundError, InvalidRequestError, AuthenticationError, NekudaValidationError, NekudaApiError
import os # For environment variables

# Best practice: Initialize client from environment variables
# Ensure NEKUDA_API_KEY is set in your environment.
# NEKUDA_BASE_URL defaults to https://api.nekuda.ai if not set.
client = NekudaClient.from_env()

# Each of your users must have a unique identifier string.
user_identifier = "example_user_e2e_flow_001"
user = client.user(user_identifier)

try:
    # Step 1: Create a mandate (intent to purchase)
    print(f"Creating mandate for user '{user_identifier}'...")
    mandate_payload = MandateData(
        product="Ultimate Gadget X",
        price=299.99,
        currency="USD",
        merchant="Future Tech Inc.",
        product_description="The latest and greatest gadget with all new features."
    )
    mandate_resp = user.create_mandate(mandate_payload)
    print(f"✅ Mandate created successfully! ID: {mandate_resp.mandate_id}")

    # Step 2: Request a card reveal token using the mandate_id from Step 1
    print(f"Requesting card reveal token for mandate ID '{mandate_resp.mandate_id}'...")
    reveal_token_resp = user.request_card_reveal_token(
        mandate_id=mandate_resp.mandate_id
    )
    print(f"🔑 Reveal token received: {reveal_token_resp.token[:15]}...")

    # Step 3: Reveal the actual card details using the token from Step 2
    print(f"Revealing card details with token...")
    card_details = user.reveal_card_details(reveal_token_resp.token)

    # Now you have the card details to use to complete the purchase
    print(f"💳 Card details revealed for user '{user_identifier}':")
    print(f"   Card Number: **** **** **** {card_details.card_number[-4:]}") # Only print last 4 for security
    print(f"   Expiry Date: {card_details.card_expiry_date}")
    print(f"   Cardholder Name: {card_details.cardholder_name}")
    print("🎉 Full flow completed successfully!")

except CardNotFoundError as e:
    print(f"Card Not Found for user '{e.user_id}': {e.message}")
    print("This often means payment details were not collected or user_id mismatch.")
except InvalidRequestError as e:
    print(f"Invalid Request: {e.message} (Code: {e.code}, HTTP Status: {e.status_code})")
    print("Check your parameters, like mandate_id format or if it exists.")
except AuthenticationError as e:
    print(f"Authentication Failed: {e.message}. Check your NEKUDA_API_KEY.")
except NekudaValidationError as e:
    print(f"Data Validation Error: {e}. This could be an issue with data sent or received.")
except NekudaApiError as e:
    print(f"nekuda API Error: {e.message} (Code: {e.code}, HTTP Status: {e.status_code})")
except NekudaError as e: # Catch any other nekuda SDK-specific errors
    print(f"A nekuda SDK error occurred: {e}")
except Exception as e: # Fallback for unexpected errors
    print(f"An unexpected error occurred: {e}")

Global Default Client Pattern

For simpler scripts or applications where dependency injection is overkill.
  • Python
  • TypeScript
from nekuda import set_default_client, get_default_client, NekudaClient, MandateData, NekudaError

# Set once at startup (e.g., in your main script or app initialization)
set_default_client(NekudaClient.from_env()) # Configured from environment

def some_business_logic_function(user_id: str, product_details: dict):
    client_instance = get_default_client() # Retrieve the globally set client
    user_context = client_instance.user(user_id)

    mandate_info = MandateData(
        product=product_details["name"],
        price=product_details["price"],
        currency=product_details["currency"],
        merchant="Global Client Store"
    )
    try:
        mandate_response = user_context.create_mandate(mandate_info)
        # ... continue with reveal token and card details ...
        print(f"Mandate {mandate_response.mandate_id} created via global client for {user_id}")
    except NekudaError as e:
        print(f"Error in business logic with global client: {e}")

# Example call
# some_business_logic_function("user_global_client_test", {"name": "Test Product", "price": 1.00, "currency": "USD"})
While convenient, the global client pattern can make it harder to manage configurations and test components in isolation in larger applications. Use with discretion.

What’s Next?

I