API Sathi docs
← All products

CRIF Credit Report

credit

Consumer credit report and score for an individual, pulled by mobile number with explicit borrower consent. SINGLE CALL — there is NO separate "send OTP" endpoint. The consent OTP is handled at YOUR end: send an OTP to the borrower’s registered mobile using your own OTP/SMS system (see the Credit Consent OTP SMS API), have them confirm it, then pass that same OTP here as proof of consent. The OTP must be UNIQUE per request. Billed on SUCCESS only (a successful pull includes the "no record found" case). TIMING: bureau pulls are slow — typical 4-9s, p95 ~8.5s. Our upstream timeout is 15s, so set your client timeout to at least 20s. A client timeout below ~10s will surface as a failure on your side for calls we complete successfully. Timeouts are never charged.

POST /gw/v1/credit-report-crif-v1/SLA p95: 8000 ms

Authentication

Pass your key in the X-API-Key header. Use a test_ key against the sandbox and a live_ key in production. Send an optional Idempotency-Key header to safely retry — the same key returns the same response for 24h.

X-API-Key: live_xxxxxxxxxxxx

Request

Endpoint: POST https://apisathi.in/gw/v1/credit-report-crif-v1/

The trailing slash is required. /v1/credit-report-crif-v1/ works; /v1/credit-report-crif-v1 returns 404 Not Found. This applies to every product.

FieldTypeRequiredConstraints
mobile_nostringrequiredpattern: ^[6-9][0-9]{9}$ · Borrower mobile number (the one consent was taken on)
first_namestringrequiredBorrower first name
last_namestringrequiredBorrower last name
otpstringrequiredThe consent OTP you generated + verified with the borrower. Max 6 digits, unique per request.
timestampstringrequiredRequest time in DDMMYYYY-HH:MM:SS format, e.g. 30072026-14:30:00
device_ipstringrequiredBorrower device IP (e.g. 203.0.113.10). Must be a valid IP.

Code snippets

curl -X POST https://apisathi.in/gw/v1/credit-report-crif-v1/ \
  -H "X-API-Key: $API_SATHI_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"mobile_no":"9876543210","first_name":"Rahul","last_name":"Verma","otp":"534216","timestamp":"30072026-14:30:00","device_ip":"203.0.113.10"}'

Response

FieldTypeRequiredConstraints
reportobjectoptionalStructured credit report + score
messagestringoptional
report_pdfstringoptionalSigned URL to the PDF report (when available)
report_xmlstringoptionalSigned URL to the XML report (when available)

Sample response

{
  "report": {
    "score": "760",
    "accounts": [
      "… structured tradelines …"
    ]
  },
  "message": "success",
  "report_pdf": "https://…/crif_report.pdf"
}

Reading a 400

A schema rejection returns INVALID_REQUEST with a details array naming the exact field. Read it before guessing — it gives you the JSON path and what was wrong with it.

{
  "error": {
    "code": "INVALID_REQUEST",
    "message": "Request body failed schema validation",
    "details": [
      { "path": "/callback_url",
        "message": "unexpected property 'callback_url' — this endpoint does not accept unknown fields" }
    ]
  }
}

Most endpoints reject unknown top-level fields outright, so an extra key you added for your own bookkeeping will fail the call. Enum errors list the accepted values, and a missing required field is named with its full path.

Error codes

CodeHTTPWhen
INVALID_INPUT422The request was rejected as invalid — either it failed OUR schema validation (malformed input; not charged), or the upstream source rejected the value you sent. NOTE: an identifier that is well-formed but simply has NO RECORD is no longer an error — it returns 200 with `verified: false` and is charged (see the result-code table below). FIX the input before retrying; retrying the same value will fail again.
INVALID_API_KEY401Missing, malformed, or revoked X-API-Key.
OUT_OF_SCOPE403API key is not scoped for this product.
INSUFFICIENT_BALANCE402Wallet balance is below the per-call sale price. Recharge and retry.
RATE_LIMITED429Per-key RPS or RPM limit exceeded. Back off and retry after the Retry-After header.
PRODUCT_DEPRECATED410This API has been retired and is no longer available. Stop calling it — it will not return. Check the catalog for the current equivalent.
ROUTER_NO_VENDOR503No healthy vendor is currently available for this product. Transient — safe to retry after a short backoff. Not charged.
VENDOR_AUTH_FAILED502Upstream vendor rejected our credentials (our config issue). Not charged.
VENDOR_ERROR502A genuine transient upstream error (the source was briefly unavailable). Safe to RETRY after a short backoff. Not charged. NOTE: this is NOT for bad input — invalid values return 422 INVALID_INPUT, not 502.
TIMEOUT504Upstream vendor did not respond within the SLA window. Safe to retry after a short backoff. Not charged.
result_code 101 — match found200The record was found. `verified: true`. Charged.
result_code 102 — invalid input200The source rejected the identifier as invalid. `verified: false`. Charged — the source billed us for the lookup. Do not retry the same value.
result_code 103 — no record found200The lookup ran and matched nothing. `verified: false`. Charged. This is a definitive answer, NOT an outage — do not retry.
result_code 106 — multiple records200More than one record matched. `verified: false`. Charged. Narrow the input to disambiguate.
result_code 104 / 105 — source failure502The upstream source failed or returned something unreadable. Returned as VENDOR_ERROR and NOT charged. This is the only case worth retrying, with backoff.

OpenAPI 3.1

Generated from this product's request/response JSON Schemas.

{
  "openapi": "3.1.0",
  "info": {
    "title": "API Sathi — CRIF Credit Report",
    "version": "1.0.0",
    "description": "Consumer credit report and score for an individual, pulled by mobile number with explicit borrower consent.\n\nSINGLE CALL — there is NO separate \"send OTP\" endpoint. The consent OTP is handled at YOUR end: send an OTP to the borrower’s registered mobile using your own OTP/SMS system (see the Credit Consent OTP SMS API), have them confirm it, then pass that same OTP here as proof of consent. The OTP must be UNIQUE per request. Billed on SUCCESS only (a successful pull includes the \"no record found\" case). \n\nTIMING: bureau pulls are slow — typical 4-9s, p95 ~8.5s. Our upstream timeout is 15s, so set your client timeout to at least 20s. A client timeout below ~10s will surface as a failure on your side for calls we complete successfully. Timeouts are never charged."
  },
  "servers": [
    {
      "url": "https://apisathi.in/gw/v1"
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Your live or test key, e.g. `live_xxxxxxxxxxxx`."
      }
    }
  },
  "paths": {
    "/credit-report-crif-v1": {
      "post": {
        "operationId": "creditReportCrifV1",
        "tags": [
          "credit"
        ],
        "summary": "CRIF Credit Report",
        "description": "Consumer credit report and score for an individual, pulled by mobile number with explicit borrower consent.\n\nSINGLE CALL — there is NO separate \"send OTP\" endpoint. The consent OTP is handled at YOUR end: send an OTP to the borrower’s registered mobile using your own OTP/SMS system (see the Credit Consent OTP SMS API), have them confirm it, then pass that same OTP here as proof of consent. The OTP must be UNIQUE per request. Billed on SUCCESS only (a successful pull includes the \"no record found\" case). \n\nTIMING: bureau pulls are slow — typical 4-9s, p95 ~8.5s. Our upstream timeout is 15s, so set your client timeout to at least 20s. A client timeout below ~10s will surface as a failure on your side for calls we complete successfully. Timeouts are never charged.",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Optional. Same key returns the same response for 24h."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "mobile_no",
                  "first_name",
                  "last_name",
                  "otp",
                  "timestamp",
                  "device_ip"
                ],
                "properties": {
                  "mobile_no": {
                    "type": "string",
                    "pattern": "^[6-9][0-9]{9}$",
                    "description": "Borrower mobile number (the one consent was taken on)"
                  },
                  "first_name": {
                    "type": "string",
                    "description": "Borrower first name"
                  },
                  "last_name": {
                    "type": "string",
                    "description": "Borrower last name"
                  },
                  "otp": {
                    "type": "string",
                    "description": "The consent OTP you generated + verified with the borrower. Max 6 digits, unique per request."
                  },
                  "timestamp": {
                    "type": "string",
                    "description": "Request time in DDMMYYYY-HH:MM:SS format, e.g. 30072026-14:30:00"
                  },
                  "device_ip": {
                    "type": "string",
                    "description": "Borrower device IP (e.g. 203.0.113.10). Must be a valid IP."
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "mobile_no": "9876543210",
                "first_name": "Rahul",
                "last_name": "Verma",
                "otp": "534216",
                "timestamp": "30072026-14:30:00",
                "device_ip": "203.0.113.10"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful, normalized response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "report": {
                      "type": "object",
                      "description": "Structured credit report + score"
                    },
                    "message": {
                      "type": "string"
                    },
                    "report_pdf": {
                      "type": "string",
                      "description": "Signed URL to the PDF report (when available)"
                    },
                    "report_xml": {
                      "type": "string",
                      "description": "Signed URL to the XML report (when available)"
                    }
                  }
                },
                "example": {
                  "report": {
                    "score": "760",
                    "accounts": [
                      "… structured tradelines …"
                    ]
                  },
                  "message": "success",
                  "report_pdf": "https://…/crif_report.pdf"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked X-API-Key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "call_id": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Wallet balance is below the per-call sale price. Recharge and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "call_id": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "API key is not scoped for this product.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "call_id": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "410": {
            "description": "This API has been retired and is no longer available. Stop calling it — it will not return. Check the catalog for the current equivalent.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "call_id": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "The request was rejected as invalid — either it failed OUR schema validation (malformed input; not charged), or the upstream source rejected the value you sent. NOTE: an identifier that is well-formed but simply has NO RECORD is no longer an error — it returns 200 with `verified: false` and is charged (see the result-code table below). FIX the input before retrying; retrying the same value will fail again.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "call_id": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Per-key RPS or RPM limit exceeded. Back off and retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "call_id": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "Upstream vendor rejected our credentials (our config issue). Not charged.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "call_id": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "No healthy vendor is currently available for this product. Transient — safe to retry after a short backoff. Not charged.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "call_id": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "504": {
            "description": "Upstream vendor did not respond within the SLA window. Safe to retry after a short backoff. Not charged.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "call_id": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}