TakaFast
Getting Started Updated Q1 2026

TakaFast Developer API Documentation

Welcome to the official TakaFast REST API. Integrate real-time payments into your e-commerce platform, mobile application, or SaaS product with just a few lines of code.

How Payment Integration Works (3 Steps)

01

Create Invoice

Your backend sends a POST /payment/create request with amount, customer info, and callback URL.

Returns payment_url
02

Customer Pays

Redirect user to payment_url where they pay securely via bKash, Nagad, Crypto (USDT, BNB, TRX), or Bank.

Instant Verification
03

Callback & Webhook

User redirects to your callback_url while our server fires a verified Webhook to fulfill the order.

Funds Auto-Settled

Authentication #

Every API request requires authentication via custom HTTP headers using your API Public Key and API Secret Key. Never expose your secret key in client-side code (browser JavaScript, mobile app bundles).

Required Request Headers
Header Type Description
x-api-key string Your store public API key (starts with pk_...)
x-api-secret string Your secret API key (starts with sk_...). Keep strictly confidential.
Content-Type string application/json for all POST / PUT requests
Where do I find my API keys? Log into your Merchant Dashboard → Store Settings → API Keys.

Base URL & Environments #

All endpoints must be prefixed with the base API URL. All requests must be made over secure HTTPS.

Base API URL https://takafast.com/api
GET /payment/methods

Get Available Payment Methods #

Fetch the active payment channels (such as bKash, Nagad, Rocket, Upay, Bank Transfer, and Crypto) configured for your store. Use this endpoint to dynamically display available payment options, account types, logos, and minimum/maximum transaction thresholds directly on your website checkout UI.

Single API Call Direct Checkout (No 2-Step API Required): You do not need to call this endpoint first! Simply pass the method name directly into /payment/create-single (e.g. "payment_method": "bkash_personal" or "bkash"). The system automatically load-balances across multiple identical accounts. See all supported method names →
curl -X GET https://takafast.com/api/payment/methods \
  -H "x-api-key: YOUR_PUBLIC_KEY" \
  -H "x-api-secret: YOUR_SECRET_KEY"
Response: 200 OK application/json
{
  "status": "success",
  "data": {
    "mobile_banking": [
      {
        "id": 1,
        "method_id": 1,
        "name": "bKash",
        "display_name": "bKash (Merchant)",
        "account_type": "Merchant",
        "currency": "BDT",
        "min_amount": 10.00,
        "max_amount": 25000.00,
        "logo_url": "https://takafast.com/storage/methods/bkash.png"
      },
      {
        "id": 2,
        "method_id": 2,
        "name": "Nagad",
        "display_name": "Nagad (Personal)",
        "account_type": "Personal",
        "currency": "BDT",
        "min_amount": 10.00,
        "max_amount": 25000.00,
        "logo_url": "https://takafast.com/storage/methods/nagad.png"
      }
    ],
    "crypto": [
      {
        "id": 5,
        "method_id": 5,
        "name": "USDT (TRC20)",
        "display_name": "USDT (TRC20)",
        "account_type": null,
        "currency": "USDT",
        "min_amount": 1.00,
        "max_amount": 10000.00,
        "logo_url": "https://takafast.com/storage/methods/usdt.png"
      }
    ]
  }
}
POST /payment/create

Create Payment Invoice #

Create a new payment session for your store. The response returns an invoice_id and a hosted payment_url. Redirect your customer to this URL to complete the checkout.

Dual Currency & Dynamic Rate Conversion

Pass "currency": "USDT" or "BDT". If billed in USDT, local MFS methods (bKash, Nagad, etc.) automatically convert the payable amount to BDT at the live exchange rate (e.g. 1 USD = 126 BDT), while USDT crypto methods charge in USD directly!

Checkout Page Themes & Languages

Checkout theme ("modern" 2-column split or "compact" clean single-card white mode) is configured directly under your Store settings in the Merchant Portal (Stores → Edit Store → Payment Page Theme). Customer checkout language can be specified per API call via the lang parameter ("bn" or "en").

Request Body Parameters application/json
Field Type Required Description
amount number Required Payment amount. Minimum: 10 BDT (or 1.00 USDT if currency is USDT). Maximum: up to 500,000 BDT.
currency string Optional Billing currency: "BDT" (Default) or "USDT". When set to "USDT", amount is charged in USD/USDT and auto-converted to BDT on local mobile channels at live rate (e.g. 1 USD = 126 BDT).
lang string Optional Customer checkout UI language: "bn" (Default - বাংলা) or "en" (English).
customer_name string Required Customer full name (Max 255 chars)
customer_email string Optional Customer email address for payment confirmation receipt
transaction_reference string Required Unique order reference generated by your store (Max 100 chars)
description string Optional Brief memo or invoice description displayed on checkout portal
method_id integer Optional Target payment method ID (from GET /payment/methods). If provided, customer bypasses the gateway selection screen and goes directly to that method's checkout.
callback_url url Required Full URL where the customer will be redirected upon completion/cancellation
curl -X POST https://takafast.com/api/payment/create \
  -H "x-api-key: YOUR_PUBLIC_KEY" \
  -H "x-api-secret: YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 10.00,
    "currency": "USDT",
    "lang": "bn",
    "customer_name": "Tariqul Islam",
    "transaction_reference": "ORD-2026-9812",
    "callback_url": "https://yourdomain.com/payment/callback"
  }'
Response: 200 OK application/json
{
  "status": "success",
  "invoice_id": "ATINV17038392001234",
  "payment_url": "https://takafast.com/methods/eyJpdiI6..."
}
POST /payment/create-single Direct Gateway

Direct Single Payment Method Checkout #

Bypass the multi-method selection screen and redirect your customer directly to a specific payment gateway (such as bKash, Nagad, Rocket, or USDT Crypto). Ideal when you already render dedicated payment buttons (e.g. "Pay with bKash" or "Pay with Crypto") on your custom store checkout.

Single API Call Direct Checkout (No 2-Step API Required):
You do not need to call GET /payment/methods first! Simply pass the method name directly, e.g. "payment_method": "bkash_personal" or "bkash".
If your store has multiple identical accounts (e.g. 4 bKash Personal SIMs), the system automatically load-balances transactions randomly across them, checking account limits so no individual SIM gets overwhelmed!
Request Body Parameters application/json
Field Type Required Description
payment_method string Recommended Target payment method name or slug, e.g. "bkash_personal", "bkash", "nagad", "upay_agent", "usdt_bep20". Eliminates the need to look up IDs! See full list below ↓
method_id integer Optional Direct numeric ID from GET /payment/methods. (Provide either payment_method or method_id).
selection_strategy string Optional Strategy when multiple same-named accounts exist: "random" (default, load-balances traffic evenly across SIMs), "least_used" (picks account with lowest used limit), or "first".
amount number Required Payment amount. Minimum 10 BDT (or 1.00 USDT). When paying BDT methods with a USDT invoice, the rate is automatically converted!
currency string Optional Payment currency: "BDT" (default) or "USDT". If USDT is selected, BDT payment methods automatically convert to BDT using current exchange rates (e.g. 1 USDT = 126 BDT).
lang string Optional Checkout interface language: "bn" (default Bangla / বাংলা) or "en" (English).
customer_name string Required Customer full name (Max 255 chars)
customer_email string Optional Customer email address for payment receipt
transaction_reference string Optional Unique order reference generated by your store (Auto-generated if omitted)
description string Optional Brief memo or invoice description displayed on checkout
callback_url url Required Full URL where the customer will be returned upon completion/cancellation
Method Names Reference Directory

All Supported Payment Method Names (payment_method)

Pass any identifier below directly in your "payment_method" field. You do not need to query numeric IDs.

Total Methods:
1

Single API Call (No 2-Step)

No need to call GET /payment/methods first! Simply send "payment_method": "bkash_personal" or "bkash" directly.

2

Multi-SIM Load Balancing

If your store has multiple identical accounts (e.g. 4 bKash Personal SIMs), the system randomly load-balances incoming transactions across them so no single SIM gets overloaded or flagged!

3

Limit Safety & Rollover

Before selecting an account, the engine verifies active status and daily limits. When a SIM reaches capacity, traffic automatically shifts to your remaining SIMs without failing transactions!

selection_strategy Optional account selection algorithms for multi-SIM stores:
"random" (default) "least_used" "first"
No method matches your filter: . Try searching for "bkash", "nagad", "usdt", or "bank".
Intelligent Fuzzy Matcher: The gateway automatically strips spaces, hyphens, underscores, and matches case-insensitively.
"bkash_personal" == "bkash-personal" == "bKash Personal"
curl -X POST https://takafast.com/api/payment/create-single \
  -H "x-api-key: YOUR_PUBLIC_KEY" \
  -H "x-api-secret: YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "payment_method": "bkash_personal",
    "amount": 10.00,
    "currency": "USDT",
    "lang": "bn",
    "customer_name": "Tariqul Islam",
    "transaction_reference": "ORD-2026-9812",
    "callback_url": "https://yourdomain.com/payment/callback"
  }'
Response: 200 OK application/json
{
  "status": "success",
  "invoice_id": "ATINV17038392005678",
  "payment_url": "https://takafast.com/payment/eyJp...?payment_method=40047",
  "currency": "USDT",
  "lang": "bn",
  "theme": "compact",
  "payment_method": {
    "id": 40047,
    "name": "bKash",
    "account_type": "Personal"
  },
  "data": {
    "invoice_id": "ATINV17038392005678",
    "payment_url": "https://takafast.com/payment/eyJp...?payment_method=40047",
    "currency": "USDT",
    "lang": "bn",
    "theme": "compact",
    "transaction_reference": "ORD-2026-9812",
    "payment_method": {
      "id": 40047,
      "name": "bKash",
      "account_type": "Personal"
    }
  }
}
GET /payment/{id}

Check Payment Status #

Verify the live status of an invoice using either the invoice_id or your store's transaction_reference.

curl -X GET https://takafast.com/api/payment/ATINV17038392001234 \
  -H "x-api-key: YOUR_PUBLIC_KEY" \
  -H "x-api-secret: YOUR_SECRET_KEY"
Response: 200 OK application/json
{
  "invoice_id": "ATINV17038392001234",
  "transaction_reference": "ORD-2026-9812",
  "status": "paid",
  "amount": 1250.00,
  "amount_paid": 1250.00,
  "paid_at": "2026-02-10T14:30:00.000Z"
}
POST /payment/batch/status

Batch Check Payment Status #

Poll multiple invoices in a single batch request to reconcile balances and bulk-check payments.

curl -X POST https://takafast.com/api/payment/batch/status \
  -H "x-api-key: YOUR_PUBLIC_KEY" \
  -H "x-api-secret: YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "ids": ["ATINV17038392001234", "ORD-2026-9813"]
  }'
Response: 200 OK application/json
{
  "status": "success",
  "total_requested": 2,
  "total_found": 2,
  "invoices": [
    {
      "invoice_id": "ATINV17038392001234",
      "transaction_reference": "ORD-2026-9812",
      "status": "paid",
      "amount": 1250.00,
      "amount_paid": 1250.00
    },
    {
      "invoice_id": "ATINV17038392001235",
      "transaction_reference": "ORD-2026-9813",
      "status": "pending",
      "amount": 500.00,
      "amount_paid": 0.00
    }
  ],
  "not_found_ids": []
}

Handling Callback & Redirect URLs #

When the user completes payment on the checkout portal (or cancels), the gateway automatically redirects the user's browser back to your callback_url with query parameters attached.

Success Redirect URL {callback_url}?status=success&invoice_id={id}&transaction_reference={ref}

Triggered when payment is successfully confirmed.

Cancel / Failure Redirect URL {callback_url}?status=cancel&invoice_id={id}&transaction_reference={ref}

Triggered when user cancels or payment expires.

Security Rule: Never fulfill physical or digital orders based solely on client-side redirect parameters. Always verify transaction status by calling GET /payment/{id} on your backend or listening to the server-to-server Webhook.
Crypto Engine Permanent Reusable Wallets

Permanent Deposit Address API #

Unlike invoice-based crypto payments where addresses expire in 15–30 minutes, the Permanent Deposit Address API assigns reusable blockchain deposit addresses to your merchant account. Ideal for Telegram bots, user deposit wallets, and crypto exchange platforms.

Zero Expiration: Once assigned, a deposit address never expires. Users can deposit funds repeatedly. Every incoming on-chain transfer is detected by our automated scanner, recorded into your ledger, and notified via instant HMAC-signed webhooks and Telegram alerts.
Dual Custody Settlement: All cryptocurrency deposits are credited directly to your merchant USD Custody Balance in USDT equivalent. TakaFast maintains two segregated custody balances: BDT Balance (৳) for local mobile banking methods, and USD Balance ($ USDT) for blockchain deposits. Each balance can be tracked and withdrawn independently.
Supported Networks & Derivation Standards
Asset Network wallet_key Default Min Deposit Confirmations
USDT BNB Smart Chain (BEP20) usdt_bep20 1.00 USDT 12 blocks (~36s)
USDT TRON (TRC20) usdt_trc20 5.00 USDT 19 blocks (~57s)
USDC BNB Smart Chain (BEP20) usdc_bep20 1.00 USDC 12 blocks (~36s)
BNB BNB Smart Chain (Native) bnb_bep20 0.005 BNB 12 blocks (~36s)
Bitcoin Bitcoin (Native SegWit) btc 0.0001 BTC 2 blocks (~20m)
Solana Solana (Native) sol 0.01 SOL 32 slots (~15s)
GET /api/deposit/networks

Get Supported Networks & Minimum Limits #

Retrieve live minimum deposit thresholds, required confirmations, and active status for all supported networks.

curl -X GET https://takafast.com/api/deposit/networks \
  -H "x-api-key: YOUR_STORE_API_KEY"
GET /api/deposit/wallets

Get All Permanent Deposit Addresses #

Returns all assigned blockchain deposit addresses for your store. If any enabled network hasn't been assigned yet, TakaFast automatically provisions it on-the-fly.

curl -X GET https://takafast.com/api/deposit/wallets \
  -H "x-api-key: YOUR_STORE_API_KEY"
GET /api/deposit/wallet/{wallet_key}

Get or Generate Address for a Specific Network #

Pass a specific wallet_key (such as usdt_bep20 or btc) to get the merchant's deposit address. Perfect for Telegram bots when a user requests a deposit.

curl -X GET https://takafast.com/api/deposit/wallet/usdt_bep20 \
  -H "x-api-key: YOUR_STORE_API_KEY"
GET /api/deposit/transactions

Query Deposit History #

Paginated history of all incoming on-chain deposits detected on your permanent addresses. Filter by status, network, or wallet_key.

GET https://takafast.com/api/deposit/transactions?status=confirmed&network=bsc&per_page=20
Real-Time

Webhooks #

Webhooks allow your application to receive instant asynchronous notifications whenever payment and blockchain deposit events occur on our servers.

Supported Webhook Event Types

Event Name Category Description
payment.completed Invoice Checkout Customer payment confirmed and funds deposited into merchant balance.
deposit.detected Blockchain Deposit New on-chain transfer detected on permanent address (awaiting confirmations).
deposit.confirmed Blockchain Deposit Deposit reached required block confirmations and is fully confirmed.
deposit.below_minimum Blockchain Deposit On-chain transfer detected but the amount is below network minimum deposit threshold.

Webhook JSON Payload Structure

Example: payment.completed HTTP POST
{
  "event": "payment.completed",
  "timestamp": "2026-02-10T14:30:00.000Z",
  "data": {
    "store_id": 5,
    "store_name": "Gadget Hub",
    "invoice_id": "ATINV17038392001234",
    "transaction_reference": "ORD-2026-9812",
    "status": "completed",
    "amount": 1250.00,
    "amount_paid": 1250.00,
    "currency": "BDT",
    "customer_name": "Tariqul Islam",
    "paid_at": "2026-02-10T14:30:00.000Z"
  }
}
HMAC-SHA256 Replay & Tamper Protection

Webhook Cryptographic Verification

To ensure incoming webhook requests genuinely originate from TakaFast and have not been altered or replayed by malicious actors, every webhook contains cryptographic signature headers signed with your dedicated Store Webhook Secret.

Your Store Webhook Secret

Each store has its own dedicated Webhook Secret key. You can find it under Merchant Dashboard → API & Webhooks → [Your Store] → Store Webhook Secret (whsec_...). Keep this secret confidential on your backend server. Never expose it in client-side code, mobile apps, or public repositories.

Header Name Description & Purpose
X-Webhook-Signature Hexadecimal HMAC-SHA256 signature generated over “{timestamp}.{raw_json}” using your Merchant Webhook Secret.
X-Signature-SHA256 Standard formatted signature header: t={timestamp},v1={hmac_sha256} (compatible with Stripe-style webhook listeners).
X-Webhook-Timestamp Unix epoch timestamp (seconds) when the notification was dispatched. Used to reject replayed requests older than 300 seconds (5 minutes).
X-Webhook-Event The event identifier (e.g. payment.completed).
Content-Type application/json

Signature Verification Steps

  1. Extract raw body: Read the raw, unmodified HTTP request payload as a string before JSON decoding.
  2. Verify timestamp: Read the X-Webhook-Timestamp header. Reject the request if the difference between current time and timestamp exceeds 300 seconds (5 minutes).
  3. Calculate HMAC: Compute hash_hmac('sha256', "{$timestamp}.{$rawBody}", $secret).
  4. Compare securely: Compare the computed hash with the header using a constant-time comparison (hash_equals in PHP, timingSafeEqual in Node.js) to prevent timing attacks.

Sample Implementation Code

<?php
// 1. Read raw body and headers
$rawBody   = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_X_WEBHOOK_TIMESTAMP'] ?? '';
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$secret    = 'YOUR_MERCHANT_WEBHOOK_SECRET'; // From Merchant Dashboard

// 2. Replay attack protection (reject if older than 5 minutes)
if (abs(time() - (int)$timestamp) > 300) {
    http_response_code(400);
    exit(json_encode(['error' => 'Timestamp tolerance exceeded']));
}

// 3. Compute expected HMAC-SHA256 signature
$expectedSignature = hash_hmac('sha256', "{$timestamp}.{$rawBody}", $secret);

// 4. Secure constant-time string comparison
if (!hash_equals($expectedSignature, $signature)) {
    http_response_code(401);
    exit(json_encode(['error' => 'Invalid webhook signature']));
}

// 5. Signature verified! Safely fulfill customer order
$event = json_decode($rawBody, true);
if ($event['event'] === 'payment.completed') {
    $invoiceId = $event['data']['invoice_id'];
    $orderRef  = $event['data']['transaction_reference'];
    $amount    = $event['data']['amount'];

    // Fulfill customer order in database...
}

// Always respond with 200 OK immediately
http_response_code(200);
echo json_encode(['received' => true]);
Webhook Security Best Practices
  • Never parse JSON before verifying HMAC: Any difference in formatting, key ordering, or whitespace will alter the signature digest. Always compute HMAC on the raw HTTP body bytes/string.
  • Idempotency: Webhooks may occasionally retry if network timeouts occur. Track processed invoice_id or transaction_reference to avoid double-crediting balances or fulfilling duplicate orders.
  • Acknowledge with 200 OK within 5s: Process heavy tasks (like sending emails or invoking external APIs) in an asynchronous background queue on your end so your webhook listener returns HTTP 200 promptly.
Security & Limits Store & Plan Policies

Store Status & Subscription Plan Limits #

Every transaction is processed strictly in the context of your merchant Store and your active Subscription Plan. Below are the store checks, domain whitelisting, and plan transaction limits enforced by the gateway.

STORE_SUSPENDED HTTP 403

The store has been suspended by system administration. The API key is deactivated and transactions cannot be processed. Contact support if you believe this is in error.

{"status": "error", "error_code": "STORE_SUSPENDED", "message": "This store has been suspended by administration..."}
STORE_INACTIVE HTTP 403

The store is turned off in your Merchant Dashboard. To resume accepting payments, navigate to Stores → Settings and set status to Active.

{"status": "error", "error_code": "STORE_INACTIVE", "message": "Store is inactive. API key is disabled."}
TRANSACTION_LIMIT_REACHED HTTP 403

Your merchant account has consumed all monthly successful transactions included in your current subscription tier. Upgrade your plan from your dashboard to unlock higher capacity.

{"status": "error", "error_code": "TRANSACTION_LIMIT_REACHED", "limit": 100, "current_usage": 100}
NO_ACTIVE_PAYMENT_METHODS HTTP 422

No active payment channels (bKash, Nagad, etc.) are currently connected or activated for this store. Ensure at least one payment method is active in store settings.

{"status": "error", "error_code": "NO_ACTIVE_PAYMENT_METHODS", "message": "No active payment methods are configured..."}
Reliability & DDoS Protection Per Store API Key · Dual-Window

API Rate Limiting #

TakaFast enforces dual-window rate limiting on all API endpoints — a per-second burst limit and a per-minute sustained limit — both scoped per Store API Key. Stricter limits apply to invoice creation to protect system stability.

Rate Limit Policy (Active)
Rule General API Invoice Creation Scope
Per Second (burst) 5 req/sec 2 req/sec Per Store API Key
Per Minute (sustained) 120 req/min 30 req/min Per Store API Key
Applies To
GET /payment/methods
GET /payment/{id}
POST /payment/batch/status
POST /payment/create
POST /payment/create-single
Rolling windows
Why two windows? A per-second limit prevents sudden burst storms (e.g., retry floods), while the per-minute limit controls sustained high traffic. The 5 req/sec limit could theoretically allow 300 req/min — so the 120 req/min cap is enforced independently.

Rate Limit Response Headers

Every API response includes these headers so you can monitor quota consumption in real time:

Header Description Example
X-RateLimit-Limit-Second Max requests allowed per second 5
X-RateLimit-Limit-Minute Max requests allowed per minute 120
X-RateLimit-Remaining-Second Requests left in current second 4
X-RateLimit-Remaining-Minute Requests left in current minute 117
Retry-After Seconds to wait — only present on 429 responses 1

429 Too Many Requests Response

HTTP 429 Too Many Requests application/json
{
  "status": "error",
  "code": 429,
  "message": "Too Many Requests. You have exceeded the API rate limit.",
  "details": {
    "limit_type": "invoice",
    "window": "per second",
    "retry_after": "1 seconds",
    "limits": {
      "per_second": 2,
      "per_minute": 30
    }
  },
  "help": "Use idempotency keys and webhooks to avoid polling. See /developers#rate-limiting for details."
}

Best Practices to Stay Under Limits

Use Webhooks, Not Polling

Register a webhook URL to receive real-time payment status updates instead of repeatedly calling GET /payment/{id}.

Implement Exponential Backoff

On a 429 response, read the Retry-After header and wait that many seconds. Use exponential backoff with jitter for resilient retry logic.

Use Idempotency Keys

Pass a unique idempotency_key with each invoice creation request to safely retry without creating duplicate invoices or burning extra quota.

Monitor X-RateLimit-Remaining-* Headers

Check X-RateLimit-Remaining-Second and X-RateLimit-Remaining-Minute on every response to proactively slow down before hitting the limit.

Retry-After Header: When rate-limited, the response always includes Retry-After: {seconds}. For per-second violations this is typically 1 — read this value to avoid unnecessary waits.

HTTP Status Codes & Errors #

The API uses standard HTTP response codes alongside structured error JSON payloads to indicate request success or failure.

Code Status Error Code / Meaning Description
200 OK — Request completed successfully.
201 Created — Invoice or payment session created successfully.
400 Bad Request INVALID_REQUEST Malformed request payload or missing JSON body.
401 Unauthorized AUTH_FAILED Invalid or missing x-api-key or x-api-secret.
403 Forbidden STORE_SUSPENDED
STORE_INACTIVE
TRANSACTION_LIMIT_REACHED
Store is suspended, inactive, or merchant plan limit has been reached.
404 Not Found NOT_FOUND The requested invoice ID or transaction reference does not exist.
422 Unprocessable Entity NO_ACTIVE_PAYMENT_METHODS
VALIDATION_ERROR
Validation error (e.g. amount out of bounds, reference already used, no active methods).
429 Too Many Requests RATE_LIMIT_EXCEEDED Rate limit exceeded. Pause and check the Retry-After response header.

Client Libraries & SDKs #

Integrate quickly using official packages and snippets for your preferred language and stack.

PHP

PHP / Laravel

Direct REST & Guzzle wrapper

composer require guzzlehttp/guzzle
JS

Node.js / Express

Axios or native fetch

npm install axios
Py

Python / Django

Requests HTTP client

pip install requests