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.
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.
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.
x-api-key: tds_live_your_key_here
Content-Type: application/json
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.
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.
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
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.
Replace {section} with the section identifier โ e.g. 194C, 194J, 194A.
Sample Request โ 194J Professional Services
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"
}
{
"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
| Field | Type | Description |
|---|---|---|
transaction_id | string | Your unique identifier for this payment. Used for idempotency and audit trail. |
pan | string | Vendor PAN in format AAAAA9999A. Used for rate determination and 206AB check. |
vendor_name | string | Vendor display name. Stored with the decision record. |
deductee_type | string | Individual, HUF, or Company. Determines applicable rate group. |
residential_status | string | Resident or Non-Resident. |
pan_status | string | See accepted values below. Affects rate applied. |
is_206ab_applicable | boolean | Whether vendor is a specified person under Section 206AB. Pass true to apply higher rate. |
is_pan_operative | boolean | Whether vendor's PAN is operative. Inoperative PAN triggers higher rate automatically. |
nature_of_payment | string | Type of payment. Must match accepted values exactly โ case sensitive. See reference below. |
credit_amount | number | Payment amount in INR. Used for threshold check and TDS calculation. |
credit_datetime | string | ISO 8601 datetime of payment. Used for financial year determination. |
Optional Fields
| Field | Type | Description |
|---|---|---|
service_type | string | Required for Section 194J only. See accepted values. |
payment_type | string | Additional payment classification for certain sections. |
aggregate_amount_ytd | number or null | Year-to-date cumulative payments to this vendor for this section. Pass null to use Auto YTD โ the API queries your stored transaction history automatically. |
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
| Value | Meaning |
|---|---|
Available | PAN provided and valid โ standard rate applies |
Not_Available | PAN not provided โ higher rate (20% or double) applies |
Invalid | PAN format invalid โ treated as not available |
Applied_For | PAN applied for but not yet received |
Response Fields
| Field | Description |
|---|---|
section | TDS section applied โ e.g. 194C, 194J |
tds_rate | Rate as decimal string โ e.g. "0.02" for 2% |
tds_amount | TDS amount to deduct in INR, rounded to 2dp |
currency | Always INR |
computed_at | Timestamp of calculation in ISO 8601 with timezone |
legal_reference | Act name, Section 393 reference, Finance Act, effective date |
calculation_reasoning | Plain-English explanation of threshold check, PAN validation, rate selection, YTD impact |
reasoning | Structured decision chain โ threshold type, rate group, decision path steps |
meta.rule_id | Opaque fingerprint of rule version active at calculation time โ cryptographic proof |
warnings | Array 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.
Query Parameters
| Parameter | Description |
|---|---|
vendor_pan | Filter by vendor PAN โ e.g. ABCDE1234F |
section | Filter by TDS section โ e.g. 194C |
financial_year | Filter by FY โ e.g. 2026-27 |
from_date | Start date โ ISO format |
to_date | End date โ ISO format |
limit | Max results per page โ default 20, max 100 |
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.
{
"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 transaction194BB โ Horse Race Winnings
Winnings from horse race.
Threshold: โน10,000 per transaction194C โ Contractors
Payments to contractors and sub-contractors. Gig platforms, logistics, construction.
Threshold: โน30,000 single ยท โน1,00,000 aggregate/year194H โ Commission / Brokerage
Commission or brokerage payments. B2B marketplaces, agent networks.
Threshold: โน15,000/year194J โ Professional / Technical
Professional fees, technical services, royalty. Consultants, agencies, SaaS.
Threshold: โน30,000/yearAccepted Values
"professional_fees" is correct. "Professional_Fees" will return a 400 error.
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
| Section | Accepted Values |
|---|---|
| 194A | interest_from_bank ยท interest_from_post_office ยท interest_payment_from_indian_company_or_business_trust |
| 194B | winnings_from_lottery ยท winnings_from_online_games |
| 194BB | horse_race_winnings |
| 194C | contractual_payment ยท job_work ยท transport_charges ยท tender_fees ยท sales_and_marketing_services |
| 194H | commission_or_brokerage |
| 194J | professional_fees ยท fees_for_technical_service ยท consultancy_fees |
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
| Value | Description |
|---|---|
Professional_Services | Legal, medical, engineering, architecture, accountancy โ 10% rate |
Technical_Services | Technical consulting, managerial, IT services โ 2% rate |
Royalty | IP licensing, patents, copyrights โ 10% rate |
Directors_Fees | Non-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.
Example โ Section Mismatch Error
POST /v1/tds/194C/compute
{
"nature_of_payment": "professional_fees", // โ This belongs to 194J, not 194C
...
}
{
"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 Used | nature_of_payment Sent | Correct Section | Rate Difference |
|---|---|---|---|
| 194C | professional_fees | 194J | 1โ2% vs 10% |
| 194C | interest_from_bank | 194A | 1โ2% vs 10% |
| 194J | contractual_payment | 194C | 10% vs 1โ2% |
| 194B | horse_race_winnings | 194BB | Same rate, different section |
| 194BB | winnings_from_lottery | 194B | Same 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.
{
"type": "invalid_request_error",
"code": "missing_parameter",
"message": "Field 'pan' is required",
"param": "pan",
"retryable": false,
"request_id": "5122f67b-8d10-44d9-8639-00f78b012f0b"
}
| HTTP | type | code | Action |
|---|---|---|---|
| 400 | invalid_request_error | missing_parameter | Fix request โ required field missing |
| 400 | invalid_request_error | invalid_parameter | Fix request โ field value invalid |
| 400 | invalid_request_error | invalid_enum_value | Check accepted values โ case sensitive |
| 400 | invalid_request_error | invalid_pan_format | PAN must match AAAAA9999A format |
| 401 | authentication_error | invalid_api_key | Check API key in x-api-key header |
| 401 | authentication_error | expired_api_key | Contact support for key renewal |
| 409 | idempotency_error | idempotency_conflict | Same key used with different payload โ investigate |
| 409 | conflict_error | duplicate_transaction | Transaction already processed โ do not retry |
| 422 | invalid_request_error | schema_validation_failed | Request body structure invalid |
| 424 | dependency_error | database_unavailable | Retry with exponential backoff |
| 429 | rate_limit_error | rate_limit_exceeded | Respect Retry-After header |
| 500 | api_error | internal_error | Retry with backoff โ contact support if persists |
Rate Limits
| Plan | Monthly Calls | Per-Minute Limit | Price |
|---|---|---|---|
| Free Trial | 500 | 100 req/min | โน0 / 30 days |
| Starter | 5,000 | 100 req/min | โน4,999/month |
| Growth | 25,000 | 100 req/min | โน14,999/month |
| Scale | 1,00,000 | 100 req/min | โน39,999/month |
| Enterprise | Custom | Custom | Contact 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
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.