Developer Documentation

TDS Compliance API

REST API for TDS calculation, reasoning storage, and audit trail management. Built for Income Tax Act 2025, effective 1 April 2026.

Base URL https://api.reginfra.com

Overview

The RegInfra API is organized around REST. It accepts JSON request bodies, returns JSON responses, and uses standard HTTP status codes. The API processes one vendor payment per request and returns a complete TDS decision with the full reasoning chain attached.

Every response includes the applicable section, rate, deduction amount, threshold state at payment time, and a plain-English justification suitable for statutory audit documentation. Decisions are stored permanently and queryable at any time.

Income Tax Act 2025 All responses include new Section 393-series references effective 1 April 2026. The API was built for the new Act from day one โ€” not retrofitted.

Test vs Live Mode

The API key you use determines the mode. Test mode keys have the prefix tds_test_ and do not create compliance records or affect your live vendor data. Live keys have the prefix tds_live_.

Authentication

All requests must include your API key in the x-api-key header. Requests without a valid key return 401 authentication_error.

Request Header
x-api-key: tds_live_your_key_here
Content-Type: application/json
Keep your API key secure. Never expose your key in client-side JavaScript, GitHub repositories, or any publicly accessible code. Each key is tied to your account โ€” all usage is logged with timestamps and IP addresses. Compromised keys can be revoked instantly from the admin panel.

Requesting Access

During beta, API keys are provisioned manually. Request a free trial at reginfra.com/#trial or email contact@reginfra.com. You will receive a test key within 24 hours on business days.

Base URL & Versioning

The current API version is v1. The version is specified in the URL path.

https://api.reginfra.com/v1/tds/{section}/compute

Breaking changes are never made to an existing version. When CBDT issues a circular โ€” rates and thresholds update automatically on the effective date. This is not a versioning event. Your integration keeps working without any changes.

Deprecation notices are issued a minimum of 6 months in advance.

Idempotency

The API supports idempotency for safely retrying requests without processing the same vendor payment twice. A duplicate TDS deduction creates both a financial error and an incorrect audit trail.

Include a unique Idempotency-Key header with every request. If a network failure occurs mid-request, retry with the same key โ€” the deduction will not be calculated or recorded twice.

Header
Idempotency-Key: INV-2026-001-v1

Key Format

Use your invoice number, transaction reference, or a UUID. Keys must be under 255 characters and are retained for 24 hours.

// Good โ€” use meaningful identifiers
Idempotency-Key: INV-2026-001
Idempotency-Key: TXN-Q1-2026-042
Idempotency-Key: VENDOR_001_2026-04-18_50000

// Bad โ€” too generic, risk of collision
Idempotency-Key: 12345
Same key + different payload = 409 conflict If you retry with the same Idempotency-Key but different request parameters, you receive a 409 idempotency_conflict error. Always use a new key for a new unique transaction.

Core Endpoint โ€” Compute TDS

This is the primary endpoint. Call it at the moment of vendor payment. It returns the correct TDS decision with the complete reasoning chain and stores the decision permanently.

POST /v1/tds/{section}/compute

Replace {section} with the section identifier โ€” e.g. 194C, 194J, 194A.

Sample Request โ€” 194J Professional Services

Request
POST https://api.reginfra.com/v1/tds/194J/compute
Content-Type: application/json
x-api-key: tds_live_your_key_here
Idempotency-Key: INV-2026-001

{
  "transaction_id": "INV-2026-001",
  "pan": "ABCDE1234F",
  "vendor_name": "ABC Consulting Pvt Ltd",
  "deductee_type": "Company",
  "residential_status": "Resident",
  "pan_status": "Available",
  "is_206ab_applicable": false,
  "is_pan_operative": true,
  "nature_of_payment": "professional_fees",
  "service_type": "Professional_Services",
  "credit_amount": 75000,
  "aggregate_amount_ytd": null,
  "credit_datetime": "2026-04-18T10:00:00"
}
Response โ€” 200 OK
{
  "section": "194J",
  "tds_rate": "0.10",
  "tds_amount": "7500.00",
  "currency": "INR",
  "computed_at": "2026-04-18T10:32:39+00:00",
  "legal_reference": {
    "act": "Income-tax Act, 2025",
    "section": "393 Table 1 S.No.(6)(iii)",
    "section_title": "Fees for professional or technical services",
    "finance_act": "Finance Act 2026",
    "effective_from": "2026-04-01"
  },
  "calculation_reasoning": {
    "threshold_check": "Amount โ‚น75,000 exceeds threshold โ‚น50,000 โ€” TDS applicable",
    "pan_validation": "Valid PAN verified โ€” standard rate applies",
    "rate_selection": "10% โ€” PAN available, Professional_Services",
    "aggregate_impact": "YTD after this payment: โ‚น75,000"
  },
  "meta": {
    "rule_id": "r_ac29066e",
    "rule_version": "1.0.0"
  },
  "warnings": []
}

Request Fields

Required Fields

FieldTypeDescription
transaction_idstringYour unique identifier for this payment. Used for idempotency and audit trail.
panstringVendor PAN in format AAAAA9999A. Used for rate determination and 206AB check.
vendor_namestringVendor display name. Stored with the decision record.
deductee_typestringIndividual, HUF, or Company. Determines applicable rate group.
residential_statusstringResident or Non-Resident.
pan_statusstringSee accepted values below. Affects rate applied.
is_206ab_applicablebooleanWhether vendor is a specified person under Section 206AB. Pass true to apply higher rate.
is_pan_operativebooleanWhether vendor's PAN is operative. Inoperative PAN triggers higher rate automatically.
nature_of_paymentstringType of payment. Must match accepted values exactly โ€” case sensitive. See reference below.
credit_amountnumberPayment amount in INR. Used for threshold check and TDS calculation.
credit_datetimestringISO 8601 datetime of payment. Used for financial year determination.

Optional Fields

FieldTypeDescription
service_typestringRequired for Section 194J only. See accepted values.
payment_typestringAdditional payment classification for certain sections.
aggregate_amount_ytdnumber or nullYear-to-date cumulative payments to this vendor for this section. Pass null to use Auto YTD โ€” the API queries your stored transaction history automatically.
Auto YTD โ€” pass null for aggregate_amount_ytd When you pass null, RegInfra automatically queries your stored transaction history for this vendor PAN and section for the current financial year. You do not need to track cumulative payments yourself.

pan_status Accepted Values

ValueMeaning
AvailablePAN provided and valid โ€” standard rate applies
Not_AvailablePAN not provided โ€” higher rate (20% or double) applies
InvalidPAN format invalid โ€” treated as not available
Applied_ForPAN applied for but not yet received

Response Fields

FieldDescription
sectionTDS section applied โ€” e.g. 194C, 194J
tds_rateRate as decimal string โ€” e.g. "0.02" for 2%
tds_amountTDS amount to deduct in INR, rounded to 2dp
currencyAlways INR
computed_atTimestamp of calculation in ISO 8601 with timezone
legal_referenceAct name, Section 393 reference, Finance Act, effective date
calculation_reasoningPlain-English explanation of threshold check, PAN validation, rate selection, YTD impact
reasoningStructured decision chain โ€” threshold type, rate group, decision path steps
meta.rule_idOpaque fingerprint of rule version active at calculation time โ€” cryptographic proof
warningsArray of advisory messages โ€” e.g. threshold approaching, PAN status flags

GET /v1/transactions

Query stored TDS decisions. Returns the full decision chain for every transaction recorded under your tenant.

GET /v1/transactions

Query Parameters

ParameterDescription
vendor_panFilter by vendor PAN โ€” e.g. ABCDE1234F
sectionFilter by TDS section โ€” e.g. 194C
financial_yearFilter by FY โ€” e.g. 2026-27
from_dateStart date โ€” ISO format
to_dateEnd date โ€” ISO format
limitMax results per page โ€” default 20, max 100
Example
GET /v1/transactions?vendor_pan=ABCDE1234F§ion=194C&financial_year=2026-27
x-api-key: tds_live_your_key_here

GET /health

Health check endpoint. Returns API status. No authentication required. Use for uptime monitoring.

GET /health
Response
{
  "status": "healthy",
  "version": "1.0.0",
  "environment": "production"
}

TDS Sections Covered

All sections are fully live in v1.0.0-beta with Income Tax Act 2025 references.

194A โ€” Interest

Interest other than on securities. Banks, NBFCs, lending platforms.

Threshold: โ‚น40,000/year (banks) ยท โ‚น5,000/year (others)

194B โ€” Lottery Winnings

Winnings from lottery, crossword puzzle, card game.

Threshold: โ‚น10,000 per transaction

194BB โ€” Horse Race Winnings

Winnings from horse race.

Threshold: โ‚น10,000 per transaction

194C โ€” Contractors

Payments to contractors and sub-contractors. Gig platforms, logistics, construction.

Threshold: โ‚น30,000 single ยท โ‚น1,00,000 aggregate/year

194H โ€” Commission / Brokerage

Commission or brokerage payments. B2B marketplaces, agent networks.

Threshold: โ‚น15,000/year

194J โ€” Professional / Technical

Professional fees, technical services, royalty. Consultants, agencies, SaaS.

Threshold: โ‚น30,000/year

Accepted Values

Case sensitive. Use values exactly as shown. "professional_fees" is correct. "Professional_Fees" will return a 400 error.
Section + nature_of_payment must be compatible. Sending interest_from_bank with section 194C returns a 400 error with the suggested correct section. This prevents silent wrong-rate deductions.

nature_of_payment by Section

SectionAccepted Values
194Ainterest_from_bank ยท interest_from_post_office ยท interest_payment_from_indian_company_or_business_trust
194Bwinnings_from_lottery ยท winnings_from_online_games
194BBhorse_race_winnings
194Ccontractual_payment ยท job_work ยท transport_charges ยท tender_fees ยท sales_and_marketing_services
194Hcommission_or_brokerage
194Jprofessional_fees ยท fees_for_technical_service ยท consultancy_fees
Cross-section values return 400. Each value above is strictly bound to its section. Sending professional_fees with section 194C โ€” or contractual_payment with section 194J โ€” returns a section mismatch error with the correct section suggested in the message.

service_type โ€” Required for 194J only

ValueDescription
Professional_ServicesLegal, medical, engineering, architecture, accountancy โ€” 10% rate
Technical_ServicesTechnical consulting, managerial, IT services โ€” 2% rate
RoyaltyIP licensing, patents, copyrights โ€” 10% rate
Directors_FeesNon-executive director remuneration โ€” 10% rate

Section Mismatch Detection

RegInfra validates that the nature_of_payment you send is compatible with the section in the URL. If they don't match, you receive a 400 error before any calculation happens.

Why this matters: The most common TDS error in India is applying Section 194C (1โ€“2%) to payments that should be 194J (10%). On a โ‚น10,00,000 payment that's โ‚น80,000 under-deduction. RegInfra catches this at the API level โ€” no ERP or TDS tool does this automatically.

Example โ€” Section Mismatch Error

Request โ€” Wrong Section
POST /v1/tds/194C/compute

{
  "nature_of_payment": "professional_fees",  // โ† This belongs to 194J, not 194C
  ...
}
Response โ€” 400 Bad Request
{
  "type": "invalid_request_error",
  "code": "invalid_parameter",
  "message": "Section mismatch โ€” 'professional_fees' is typically taxed under 194J (Professional/Technical fees), not Section 194C. Please verify the correct section and resubmit.",
  "param": "nature_of_payment",
  "retryable": false
}

Common Mismatches Caught

Section Usednature_of_payment SentCorrect SectionRate Difference
194Cprofessional_fees194J1โ€“2% vs 10%
194Cinterest_from_bank194A1โ€“2% vs 10%
194Jcontractual_payment194C10% vs 1โ€“2%
194Bhorse_race_winnings194BBSame rate, different section
194BBwinnings_from_lottery194BSame rate, different section

Error Codes

All errors return a consistent JSON structure. Always switch on error.code โ€” never on error.message, which may change between versions.

Error Response Structure
{
  "type": "invalid_request_error",
  "code": "missing_parameter",
  "message": "Field 'pan' is required",
  "param": "pan",
  "retryable": false,
  "request_id": "5122f67b-8d10-44d9-8639-00f78b012f0b"
}
HTTPtypecodeAction
400invalid_request_errormissing_parameterFix request โ€” required field missing
400invalid_request_errorinvalid_parameterFix request โ€” field value invalid
400invalid_request_errorinvalid_enum_valueCheck accepted values โ€” case sensitive
400invalid_request_errorinvalid_pan_formatPAN must match AAAAA9999A format
401authentication_errorinvalid_api_keyCheck API key in x-api-key header
401authentication_errorexpired_api_keyContact support for key renewal
409idempotency_erroridempotency_conflictSame key used with different payload โ€” investigate
409conflict_errorduplicate_transactionTransaction already processed โ€” do not retry
422invalid_request_errorschema_validation_failedRequest body structure invalid
424dependency_errordatabase_unavailableRetry with exponential backoff
429rate_limit_errorrate_limit_exceededRespect Retry-After header
500api_errorinternal_errorRetry with backoff โ€” contact support if persists

Rate Limits

PlanMonthly CallsPer-Minute LimitPrice
Free Trial500100 req/minโ‚น0 / 30 days
Starter5,000100 req/minโ‚น4,999/month
Growth25,000100 req/minโ‚น14,999/month
Scale1,00,000100 req/minโ‚น39,999/month
EnterpriseCustomCustomContact us

When you exceed the per-minute rate limit, the API returns 429 rate_limit_exceeded. Implement exponential backoff in your integration.

Upcoming Features

These features are on the active roadmap and will be available in upcoming releases. If any of these are blocking your integration, contact us โ€” we prioritise based on demand.

Pre-Payment Validation โ€” POST /v1/tds/{section}/validate

  • Call before payment executes โ€” not after
  • Returns go/no-go decision with HIGH / MEDIUM / LOW risk flag
  • Catches wrong rate before money moves โ€” not for audit after the fact
  • Threshold warning if vendor approaching annual limit

Section Mismatch Detection

  • Flags when caller-provided section doesn't match payment nature
  • 194C vs 194J is the most common misclassification โ€” 1% vs 10% difference
  • Returns explanation and suggested correct section
  • Confidence score on every classification

26Q Filing Export โ€” GET /v1/reports/26Q

  • Complete quarter TDS data in one API call
  • Finance-ready output โ€” section-wise, vendor-wise, period-wise
  • Reduces quarterly filing prep from days to minutes

206AB Status Change Detection

  • Detects when vendor's 206AB status changed since last payment
  • Auto-updates applicable rate โ€” no manual monitoring needed
  • Status change flag returned in response

Important Disclaimer

RegInfra is a technology tool โ€” not a tax advisor or Chartered Accountant. Outputs from this API are advisory only and do not constitute professional tax advice. You remain solely responsible for the accuracy of your TDS deductions, filings, and payments to the Income Tax Department. RegInfra shall not be liable for any tax demand, interest, penalty, or notice arising from reliance on API outputs without independent professional verification.

Specific limitations to be aware of:

  • 206AB status: The API applies the higher 206AB rate only when you pass is_206ab_applicable: true. You are responsible for maintaining current 206AB status per vendor and updating it after the annual list refresh (post July 31 each year). RegInfra does not independently verify 206AB status against TRACES.
  • Rule currency: We make reasonable efforts to keep the rule engine current with CBDT circulars and Finance Act changes. However, there may be a lag between a new circular and its incorporation into the API. Always verify against the official gazette for time-sensitive high-value transactions.
  • Section classification: The correct TDS section for a payment depends on the specific facts of the transaction. Where facts are ambiguous โ€” particularly for 194C vs 194J โ€” we recommend independent CA review before deducting.

By using this API you acknowledge these limitations. Full terms are available at reginfra.com/terms.

Support

Email contact@reginfra.com for integration help, bug reports, or feature requests. Response time during beta: within 24 hours on business days. For urgent issues, include URGENT in the subject line.

Beta users who provide feedback and report bugs receive extended free access and priority support.