E-Invoice
Update IRP Configuration
Configure or update the Invoice Registration Portal (IRP) credentials for e-invoicing.
PUT
/
v1
/
settings
/
irp
Create or update IRP credentials
curl --request PUT \
--url https://billing.example.com/v1/settings/irp \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"id": "<string>",
"tenant_id": "<string>",
"client_id": "<string>",
"client_secret": "<string>",
"username": "<string>",
"password": "<string>",
"gstin": "<string>",
"is_enabled": true
}
'import requests
url = "https://billing.example.com/v1/settings/irp"
payload = {
"id": "<string>",
"tenant_id": "<string>",
"client_id": "<string>",
"client_secret": "<string>",
"username": "<string>",
"password": "<string>",
"gstin": "<string>",
"is_enabled": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
id: '<string>',
tenant_id: '<string>',
client_id: '<string>',
client_secret: '<string>',
username: '<string>',
password: '<string>',
gstin: '<string>',
is_enabled: true
})
};
fetch('https://billing.example.com/v1/settings/irp', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://billing.example.com/v1/settings/irp",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'id' => '<string>',
'tenant_id' => '<string>',
'client_id' => '<string>',
'client_secret' => '<string>',
'username' => '<string>',
'password' => '<string>',
'gstin' => '<string>',
'is_enabled' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://billing.example.com/v1/settings/irp"
payload := strings.NewReader("{\n \"id\": \"<string>\",\n \"tenant_id\": \"<string>\",\n \"client_id\": \"<string>\",\n \"client_secret\": \"<string>\",\n \"username\": \"<string>\",\n \"password\": \"<string>\",\n \"gstin\": \"<string>\",\n \"is_enabled\": true\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://billing.example.com/v1/settings/irp")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"id\": \"<string>\",\n \"tenant_id\": \"<string>\",\n \"client_id\": \"<string>\",\n \"client_secret\": \"<string>\",\n \"username\": \"<string>\",\n \"password\": \"<string>\",\n \"gstin\": \"<string>\",\n \"is_enabled\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://billing.example.com/v1/settings/irp")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"id\": \"<string>\",\n \"tenant_id\": \"<string>\",\n \"client_id\": \"<string>\",\n \"client_secret\": \"<string>\",\n \"username\": \"<string>\",\n \"password\": \"<string>\",\n \"gstin\": \"<string>\",\n \"is_enabled\": true\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "<string>",
"tenant_id": "<string>",
"environment": "sandbox",
"client_id": "<string>",
"client_secret": "<string>",
"username": "<string>",
"password": "<string>",
"gstin": "<string>",
"is_enabled": true
},
"message": "<string>"
}{
"error": {
"code": "BAD_REQUEST",
"message": "<string>"
}
}{
"error": {
"code": "BAD_REQUEST",
"message": "<string>"
}
}Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
client_id | string | Yes | The OAuth client ID provided by the IRP portal. |
client_secret | string | Yes | The OAuth client secret provided by the IRP portal. |
username | string | Yes | Your IRP portal login username. |
password | string | Yes | Your IRP portal login password. |
gstin | string | Yes | The 15-character GSTIN to associate with this IRP configuration. |
environment | string | Yes | Target environment. One of: sandbox, production. |
is_enabled | boolean | Yes | Set to true to enable e-invoicing, false to disable. |
Example Request
curl -X PUT https://api.recurso.dev/v1/settings/irp \
-H "Authorization: Bearer rsk_live_7f3a9b2c1d4e8f0a" \
-H "Content-Type: application/json" \
-d '{
"client_id": "ABCD1234EF",
"client_secret": "sk_irp_9f8e7d6c5b4a3210",
"username": "recurso_einv",
"password": "s3cureP@ssw0rd",
"gstin": "29AABCT1332L1ZM",
"environment": "production",
"is_enabled": true
}'
Response
{
"client_id": "ABCD1234EF",
"client_secret": "sk_irp_****3210",
"username": "recurso_einv",
"password": "****",
"gstin": "29AABCT1332L1ZM",
"environment": "production",
"is_enabled": true,
"last_token_refresh": "2026-06-23T16:30:00Z",
"created_at": "2025-11-01T08:00:00Z",
"updated_at": "2026-06-23T16:30:00Z"
}
Notes
- Sensitive fields (
client_secret,password) are masked in the response for security. - Recurso automatically manages IRP token refresh. The
last_token_refreshfield shows when the OAuth token was last renewed. - Use
environment: "sandbox"for testing before enabling production e-invoicing. - Setting
is_enabled: falsepauses all e-invoice generation without removing credentials.
To retrieve the current IRP configuration, use
GET /v1/settings/irp with the same authorization header. The GET endpoint returns the same response structure with sensitive fields masked.Ensure your IRP credentials are valid before switching to
production. Invalid credentials will cause all e-invoice submissions to fail.Authorizations
Tenant API key obtained from POST /auth/register or POST /v1/developer/keys.
Query Parameters
Legal entity to scope the tax config to (Multi-Entity Books). Omit for the tenant's primary entity / default config.
Body
application/json
⌘I
Create or update IRP credentials
curl --request PUT \
--url https://billing.example.com/v1/settings/irp \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"id": "<string>",
"tenant_id": "<string>",
"client_id": "<string>",
"client_secret": "<string>",
"username": "<string>",
"password": "<string>",
"gstin": "<string>",
"is_enabled": true
}
'import requests
url = "https://billing.example.com/v1/settings/irp"
payload = {
"id": "<string>",
"tenant_id": "<string>",
"client_id": "<string>",
"client_secret": "<string>",
"username": "<string>",
"password": "<string>",
"gstin": "<string>",
"is_enabled": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
id: '<string>',
tenant_id: '<string>',
client_id: '<string>',
client_secret: '<string>',
username: '<string>',
password: '<string>',
gstin: '<string>',
is_enabled: true
})
};
fetch('https://billing.example.com/v1/settings/irp', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://billing.example.com/v1/settings/irp",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'id' => '<string>',
'tenant_id' => '<string>',
'client_id' => '<string>',
'client_secret' => '<string>',
'username' => '<string>',
'password' => '<string>',
'gstin' => '<string>',
'is_enabled' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://billing.example.com/v1/settings/irp"
payload := strings.NewReader("{\n \"id\": \"<string>\",\n \"tenant_id\": \"<string>\",\n \"client_id\": \"<string>\",\n \"client_secret\": \"<string>\",\n \"username\": \"<string>\",\n \"password\": \"<string>\",\n \"gstin\": \"<string>\",\n \"is_enabled\": true\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://billing.example.com/v1/settings/irp")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"id\": \"<string>\",\n \"tenant_id\": \"<string>\",\n \"client_id\": \"<string>\",\n \"client_secret\": \"<string>\",\n \"username\": \"<string>\",\n \"password\": \"<string>\",\n \"gstin\": \"<string>\",\n \"is_enabled\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://billing.example.com/v1/settings/irp")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"id\": \"<string>\",\n \"tenant_id\": \"<string>\",\n \"client_id\": \"<string>\",\n \"client_secret\": \"<string>\",\n \"username\": \"<string>\",\n \"password\": \"<string>\",\n \"gstin\": \"<string>\",\n \"is_enabled\": true\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "<string>",
"tenant_id": "<string>",
"environment": "sandbox",
"client_id": "<string>",
"client_secret": "<string>",
"username": "<string>",
"password": "<string>",
"gstin": "<string>",
"is_enabled": true
},
"message": "<string>"
}{
"error": {
"code": "BAD_REQUEST",
"message": "<string>"
}
}{
"error": {
"code": "BAD_REQUEST",
"message": "<string>"
}
}