# External API Curl Guide This file documents outbound HTTP calls made by the app or maintenance scripts. Client credentials that are hardcoded in the codebase are filled in below. Keep placeholders only for runtime data such as national codes, plate values, tokens returned by login calls, and payload files. ## Common Notes - Internal app URLs in Swagger, localhost examples, and file download URLs are not listed. - Package/build-time network calls such as npm registry, Sonar, and Docker setup are not runtime app requests. - `firstValueFrom(this.httpService...)`, `lastValueFrom(this.httpService...)`, and `fetch(...)` call sites were checked. - Several integrations cache bearer tokens in memory for about 55 minutes. - Some Fanavaran credentials and the Map.ir API key are hardcoded in source. Treat them as sensitive and consider moving/rotating them. ## Fanavaran API Manager Host: ```sh FANAVARAN_BASE_URL="https://apimanager.iraneit.com/BimeApiManager/api" FANAVARAN_BIME_URL="$FANAVARAN_BASE_URL/BimeApi/v2.0" ``` Used by: - `src/fanavaran/fanavaran-lookup.service.ts` - `src/fanavaran/fanavaran-lookup.config.ts` - `src/claim-request-management/claim-request-management.service.ts` ### Sequence 1. Get `appToken`. 2. Login with `appToken` to get `authenticationToken`. 3. Call lookup, policy inquiry, or submit endpoint with `authenticationToken`, `CorpId`, `ContractId`, and `Location`. ### Auth Script Use this when you only need fresh Fanavaran tokens and do not want to copy the curl commands manually: ```sh scripts/fanavaran-auth.sh tejaratno scripts/fanavaran-auth.sh parsian ``` The script stores raw responses and reusable variables under `files/fanavaran-auth//`. For example: ```sh source files/fanavaran-auth/tejaratno/tokens.env curl -X GET "$FANAVARAN_BIME_URL/car/base-info/accident-causes" \ -H "authenticationToken: $AUTHENTICATION_TOKEN" \ -H "CorpId: $CORP_ID" \ -H "ContractId: $CONTRACT_ID" \ -H "Location: $LOCATION" \ -H "Content-Type: application/json" ``` ### Tenant Credentials The app supports these Fanavaran client profiles: | Client | appname | secret | userName | password | CorpId | ContractId | Location | | --- | --- | --- | --- | --- | --- | --- | --- | | tejaratno | `fanhab` | `5Fa@N#A2B` | `fanhabUser` | `Fan#@2U$3er` | `3539` | `263` | `100` | | parsian | `ParsianService` | `P@r30@n$erv!ce` | `ParsianServiceUser` | `P@r30@n123` | `543` | `28` | `210050` | Set the client variables before running. These values come from `src/core/config/fanavaran-client.config.ts` and match `src/claim-request-management/claim-request-management.service.ts`. Tejaratno: ```sh FANAVARAN_CLIENT="tejaratno" APP_NAME='fanhab' APP_SECRET='5Fa@N#A2B' FANAVARAN_USERNAME='fanhabUser' FANAVARAN_PASSWORD='Fan#@2U$3er' CORP_ID='3539' CONTRACT_ID='263' LOCATION='100' ``` Parsian: ```sh FANAVARAN_CLIENT="parsian" APP_NAME='ParsianService' APP_SECRET='P@r30@n$erv!ce' FANAVARAN_USERNAME='ParsianServiceUser' FANAVARAN_PASSWORD='P@r30@n123' CORP_ID='543' CONTRACT_ID='28' LOCATION='210050' ``` ### 1. Get App Token The app sends an empty string body, deletes `Content-Type`, and keeps `Content-Length: 0`. ```sh curl -i -X POST "$FANAVARAN_BASE_URL/EITAuthentication/GetAppToken" \ -H "appname: $APP_NAME" \ -H "secret: $APP_SECRET" \ -H "Content-Length: 0" ``` The token is returned in a response header named `appToken` or `apptoken`. ```sh curl -sS -D /tmp/fanavaran-app-token.headers -o /tmp/fanavaran-app-token.body \ -X POST "$FANAVARAN_BASE_URL/EITAuthentication/GetAppToken" \ -H "appname: $APP_NAME" \ -H "secret: $APP_SECRET" \ -H "Content-Length: 0" APP_TOKEN="$(awk -F': ' 'tolower($1)=="apptoken" {gsub(/\r/,"",$2); print $2}' /tmp/fanavaran-app-token.headers)" printf 'APP_TOKEN=%s\n' "$APP_TOKEN" ``` ### 2. Login Use the `APP_TOKEN` returned by the immediately previous GetAppToken request. Do not reuse an old app token pasted from logs or another machine; the app does not do that. ```sh curl -i -X POST "$FANAVARAN_BASE_URL/EITAuthentication/Login" \ -H "appToken: $APP_TOKEN" \ -H "userName: $FANAVARAN_USERNAME" \ -H "password: $FANAVARAN_PASSWORD" \ -H "Content-Length: 0" ``` The token is returned in a response header or body field named `authenticationToken`, `authenticationtoken`, or `authentication_token`. ```sh curl -sS -D /tmp/fanavaran-login.headers -o /tmp/fanavaran-login.body \ -X POST "$FANAVARAN_BASE_URL/EITAuthentication/Login" \ -H "appToken: $APP_TOKEN" \ -H "userName: $FANAVARAN_USERNAME" \ -H "password: $FANAVARAN_PASSWORD" \ -H "Content-Length: 0" AUTHENTICATION_TOKEN="$(awk -F': ' 'tolower($1)=="authenticationtoken" {gsub(/\r/,"",$2); print $2}' /tmp/fanavaran-login.headers)" if [ -z "$AUTHENTICATION_TOKEN" ]; then AUTHENTICATION_TOKEN="$(node -e 'const fs=require("fs"); const body=fs.readFileSync("/tmp/fanavaran-login.body","utf8"); try { const json=JSON.parse(body); console.log(json.authenticationToken || json.authenticationtoken || json.authentication_token || ""); } catch { console.log(""); }')" fi printf 'AUTHENTICATION_TOKEN=%s\n' "$AUTHENTICATION_TOKEN" ``` If login returns `نام کاربر یا رمز عبور صحیح نیست` for `tejaratno`, first check that `APP_TOKEN` was generated with `appname: fanhab` and `secret: 5Fa@N#A2B` in the same sequence. The runtime code calls `GetAppToken` first, then passes that fresh header value to `Login`; it does not use a static value such as `182197f6-7b41-47b4-9b18-5bfcbc027f2e`. ### Ready-To-Run Auth Sequences Tejaratno: ```sh FANAVARAN_BASE_URL="https://apimanager.iraneit.com/BimeApiManager/api" FANAVARAN_BIME_URL="$FANAVARAN_BASE_URL/BimeApi/v2.0" FANAVARAN_CLIENT="tejaratno" APP_NAME='fanhab' APP_SECRET='5Fa@N#A2B' FANAVARAN_USERNAME='fanhabUser' FANAVARAN_PASSWORD='Fan#@2U$3er' CORP_ID='3539' CONTRACT_ID='263' LOCATION='100' curl -sS -D /tmp/fanavaran-app-token.headers -o /tmp/fanavaran-app-token.body \ -X POST "$FANAVARAN_BASE_URL/EITAuthentication/GetAppToken" \ -H "appname: $APP_NAME" \ -H "secret: $APP_SECRET" \ -H "Content-Length: 0" APP_TOKEN="$(awk -F': ' 'tolower($1)=="apptoken" {gsub(/\r/,"",$2); print $2}' /tmp/fanavaran-app-token.headers)" curl -sS -D /tmp/fanavaran-login.headers -o /tmp/fanavaran-login.body \ -X POST "$FANAVARAN_BASE_URL/EITAuthentication/Login" \ -H "appToken: $APP_TOKEN" \ -H "userName: $FANAVARAN_USERNAME" \ -H "password: $FANAVARAN_PASSWORD" \ -H "Content-Length: 0" AUTHENTICATION_TOKEN="$(awk -F': ' 'tolower($1)=="authenticationtoken" {gsub(/\r/,"",$2); print $2}' /tmp/fanavaran-login.headers)" if [ -z "$AUTHENTICATION_TOKEN" ]; then AUTHENTICATION_TOKEN="$(node -e 'const fs=require("fs"); const body=fs.readFileSync("/tmp/fanavaran-login.body","utf8"); try { const json=JSON.parse(body); console.log(json.authenticationToken || json.authenticationtoken || json.authentication_token || ""); } catch { console.log(""); }')" fi printf 'APP_TOKEN=%s\nAUTHENTICATION_TOKEN=%s\n' "$APP_TOKEN" "$AUTHENTICATION_TOKEN" ``` Parsian: ```sh FANAVARAN_BASE_URL="https://apimanager.iraneit.com/BimeApiManager/api" FANAVARAN_BIME_URL="$FANAVARAN_BASE_URL/BimeApi/v2.0" FANAVARAN_CLIENT="parsian" APP_NAME='ParsianService' APP_SECRET='P@r30@n$erv!ce' FANAVARAN_USERNAME='ParsianServiceUser' FANAVARAN_PASSWORD='P@r30@n123' CORP_ID='543' CONTRACT_ID='28' LOCATION='210050' curl -sS -D /tmp/fanavaran-app-token.headers -o /tmp/fanavaran-app-token.body \ -X POST "$FANAVARAN_BASE_URL/EITAuthentication/GetAppToken" \ -H "appname: $APP_NAME" \ -H "secret: $APP_SECRET" \ -H "Content-Length: 0" APP_TOKEN="$(awk -F': ' 'tolower($1)=="apptoken" {gsub(/\r/,"",$2); print $2}' /tmp/fanavaran-app-token.headers)" curl -sS -D /tmp/fanavaran-login.headers -o /tmp/fanavaran-login.body \ -X POST "$FANAVARAN_BASE_URL/EITAuthentication/Login" \ -H "appToken: $APP_TOKEN" \ -H "userName: $FANAVARAN_USERNAME" \ -H "password: $FANAVARAN_PASSWORD" \ -H "Content-Length: 0" AUTHENTICATION_TOKEN="$(awk -F': ' 'tolower($1)=="authenticationtoken" {gsub(/\r/,"",$2); print $2}' /tmp/fanavaran-login.headers)" if [ -z "$AUTHENTICATION_TOKEN" ]; then AUTHENTICATION_TOKEN="$(node -e 'const fs=require("fs"); const body=fs.readFileSync("/tmp/fanavaran-login.body","utf8"); try { const json=JSON.parse(body); console.log(json.authenticationToken || json.authenticationtoken || json.authentication_token || ""); } catch { console.log(""); }')" fi printf 'APP_TOKEN=%s\nAUTHENTICATION_TOKEN=%s\n' "$APP_TOKEN" "$AUTHENTICATION_TOKEN" ``` ### 3A. Lookup Endpoints These are fetched on demand and cached under `files/fanavaran-lookups//`. ```sh curl -X GET "$FANAVARAN_BIME_URL/car/base-info/accident-causes" \ -H "authenticationToken: $AUTHENTICATION_TOKEN" \ -H "CorpId: $CORP_ID" \ -H "ContractId: $CONTRACT_ID" \ -H "Location: $LOCATION" \ -H "Content-Type: application/json" curl -X GET "$FANAVARAN_BIME_URL/car/code-list/accident-report-type" \ -H "authenticationToken: $AUTHENTICATION_TOKEN" \ -H "CorpId: $CORP_ID" \ -H "ContractId: $CONTRACT_ID" \ -H "Location: $LOCATION" \ -H "Content-Type: application/json" curl -X GET "$FANAVARAN_BIME_URL/car/base-info/vehicle-use-types" \ -H "authenticationToken: $AUTHENTICATION_TOKEN" \ -H "CorpId: $CORP_ID" \ -H "ContractId: $CONTRACT_ID" \ -H "Location: $LOCATION" \ -H "Content-Type: application/json" curl -X GET "$FANAVARAN_BIME_URL/car/code-list/dmg-pay-method" \ -H "authenticationToken: $AUTHENTICATION_TOKEN" \ -H "CorpId: $CORP_ID" \ -H "ContractId: $CONTRACT_ID" \ -H "Location: $LOCATION" \ -H "Content-Type: application/json" curl -X GET "$FANAVARAN_BIME_URL/car/base-info/driving-licence-types" \ -H "authenticationToken: $AUTHENTICATION_TOKEN" \ -H "CorpId: $CORP_ID" \ -H "ContractId: $CONTRACT_ID" \ -H "Location: $LOCATION" \ -H "Content-Type: application/json" curl -X GET "$FANAVARAN_BIME_URL/car/code-list/accident-culprit-type" \ -H "authenticationToken: $AUTHENTICATION_TOKEN" \ -H "CorpId: $CORP_ID" \ -H "ContractId: $CONTRACT_ID" \ -H "Location: $LOCATION" \ -H "Content-Type: application/json" curl -X GET "$FANAVARAN_BIME_URL/car/base-info/vehicle-kinds" \ -H "authenticationToken: $AUTHENTICATION_TOKEN" \ -H "CorpId: $CORP_ID" \ -H "ContractId: $CONTRACT_ID" \ -H "Location: $LOCATION" \ -H "Content-Type: application/json" curl -X GET "$FANAVARAN_BIME_URL/car/vehicles/inquiry-by-vin?vin=IRNKAEK4150012345" \ -H "authenticationToken: $AUTHENTICATION_TOKEN" \ -H "CorpId: $CORP_ID" \ -H "ContractId: $CONTRACT_ID" \ -H "Location: $LOCATION" \ -H "Content-Type: application/json" ``` ### 3B. Policy Inquiry By National Code Used before Fanavaran claim submit to resolve a `PolicyId` when possible. ```sh NATIONAL_CODE="" curl -X GET "$FANAVARAN_BIME_URL/common/Policies/inquiry-my-policies?InsuranceLineId=5&NationalCode=$NATIONAL_CODE" \ -H "authenticationToken: $AUTHENTICATION_TOKEN" \ -H "CorpId: $CORP_ID" \ -H "ContractId: $CONTRACT_ID" \ -H "Location: $LOCATION" \ -H "Content-Type: application/json" ``` ### 3C. Third-Party Car Financial Claim Submit `fanavaranData` is built internally from a claim case/request. The shape is large; capture an app log or preview output and save it as JSON before replaying. ```sh curl -X POST "$FANAVARAN_BIME_URL/car/third-party-car-financial-claims" \ -H "authenticationToken: $AUTHENTICATION_TOKEN" \ -H "CorpId: $CORP_ID" \ -H "ContractId: $CONTRACT_ID" \ -H "Location: $LOCATION" \ -H "Content-Type: application/json" \ --data @fanavaran-claim-submit.json ``` ## Tejarat Inquiry Provider Default base URL: ```sh TEJARAT_INQUIRY_BASE_URL="${TEJARAT_INQUIRY_BASE_URL:-http://82.99.202.245:3027}" TEJARAT_INQUIRY_EMAIL='xxx@example.com' TEJARAT_INQUIRY_PASSWORD='123321' ``` Used by `src/sand-hub/sand-hub.service.ts` for third-party plate and car-body plate inquiries when ESG is not selected. ### Sequence 1. Login to `/user/login`. 2. Use returned `accessToken` as `Authorization: Bearer ...`. 3. Call inquiry endpoint. ### Login ```sh curl -X POST "$TEJARAT_INQUIRY_BASE_URL/user/login" \ -H "Accept: */*" \ -H "Content-Type: application/json" \ --data '{ "email": "'"$TEJARAT_INQUIRY_EMAIL"'", "password": "'"$TEJARAT_INQUIRY_PASSWORD"'" }' ``` ```sh TEJARAT_ACCESS_TOKEN="" ``` ### Third-Party Plate / Policy Block Inquiry ```sh curl -X POST "$TEJARAT_INQUIRY_BASE_URL/block-inquiry-tejarat" \ -H "Authorization: Bearer $TEJARAT_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ --data '{ "leftTwoDigits": "12", "serialLetter": "ب", "threeDigits": "345", "rightTwoDigits": "67", "nationalCode": "0012345678" }' ``` ### Car-Body Plate Inquiry ```sh curl -X POST "$TEJARAT_INQUIRY_BASE_URL/block-inquiry-tejarat/badane" \ -H "Authorization: Bearer $TEJARAT_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ --data '{ "part1": 12, "part2": "ب", "part3": 345, "part4": 67, "nationalCode": "0012345678" }' ``` ## ESG Inquiry Provider Default/fallback base URL in some call sites: ```sh ESG_URL="${ESG_URL:-http://192.168.20.22:8085}" ``` Used by `src/sand-hub/sand-hub.service.ts` for selected tenants, for example when `CLIENT_ID=8`. ### Sequence 1. Login to `/auth/login`. 2. Use returned `accessToken` as `Authorization: Bearer ...`. 3. Call the inquiry endpoint. ### Login ```sh curl -X POST "$ESG_URL/auth/login" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ --data '{ "username": "'"$ESG_USERNAME"'", "password": "'"$ESG_PASSWORD"'" }' ``` ```sh ESG_ACCESS_TOKEN="" ``` ### Policy By Plate ```sh curl -X POST "$ESG_URL/inquiry/policyByPlate" \ -H "Authorization: Bearer $ESG_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ --data '{ "nationalCode": "0012345678", "plk1": "12", "plk2": "ب", "plk3": "345", "plksrl": "67" }' ``` ### Person Inquiry ESG expects Jalali birth date, normalized as `YYYY-MM-DD`. ```sh curl -X POST "$ESG_URL/inquiry/person" \ -H "Authorization: Bearer $ESG_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ --data '{ "nationalCode": "0012345678", "birthDate": "1378-11-24", "dateHasPostfix": 0 }' ``` ### Sheba Validation ```sh curl -X POST "$ESG_URL/inquiry/sheba" \ -H "Authorization: Bearer $ESG_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ --data '{ "accountOwnerType": "1", "nationalCode": "0012345678", "legalId": "", "sheba": "IR000000000000000000000000" }' ``` ## SandHub Provider Used by `src/sand-hub/sand-hub.service.ts` for legacy inquiry flows. Environment: ```sh SANHUB_BASE_URL='http://82.99.202.245:3027' SANHUB_URL_LOGIN='http://82.99.202.245:3027/user/login' SANHUB_USERNAME='default@admin.com' SANHUB_PASSWORD='123321' ``` ### Sequence 1. Login through `SANHUB_URL_LOGIN`. 2. Use returned `accessToken` as `Authorization: Bearer ...`. 3. Call the required endpoint under `SANHUB_BASE_URL`. ### Login ```sh curl -X POST "$SANHUB_URL_LOGIN" \ -H "Content-Type: application/json" \ --data '{ "email": "'"$SANHUB_USERNAME"'", "password": "'"$SANHUB_PASSWORD"'" }' ``` ```sh SANHUB_ACCESS_TOKEN="" ``` ### Third-Party Plate / Policy Block Inquiry ```sh curl -X POST "$SANHUB_BASE_URL/block-inquiry-tejarat" \ -H "Authorization: Bearer $SANHUB_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ --data '{ "leftTwoDigits": "12", "serialLetter": "ب", "threeDigits": "345", "rightTwoDigits": "67", "nationalCode": "0012345678" }' ``` ### Personal Inquiry The app converts Jalali birth dates to Gregorian before sending to SandHub. ```sh curl -X POST "$SANHUB_BASE_URL/personal-inquiry/tejarat-no" \ -H "Authorization: Bearer $SANHUB_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ --data '{ "nationalCode": "0012345678", "birthdate": "1999-02-13" }' ``` ### Driving License Check ```sh curl -X POST "$SANHUB_BASE_URL/driver-license-check" \ -H "Authorization: Bearer $SANHUB_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ --data '{ "driverLicenseNumber": "1234567890", "nationalCode": "0012345678" }' ``` ### Car Ownership ```sh curl -X POST "$SANHUB_BASE_URL/ownership" \ -H "Authorization: Bearer $SANHUB_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ --data '{ "Plk1": "12", "Plk2": "ب", "Plk3": "345", "plkSrl": "67", "nationalCode": "0012345678" }' ``` ### Sheba Validation ```sh curl -X POST "$SANHUB_BASE_URL/sheba/sheba-tejaratno" \ -H "Authorization: Bearer $SANHUB_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ --data '{ "AccountOwnerType": "1", "NationalId": "0012345678", "ShebaId": "IR000000000000000000000000" }' ``` ## Map.ir Reverse Geocoding Used by `src/claim-request-management/claim-request-management.service.ts`. ```sh MAP_IR_API_KEY='eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImI5ZDZjMThkNDRjZjc2OWI2Yjk1ODcyMGFjYmEzMmRiN2NhZjg0Zjk4OTRlMjZiZDg0Yzg3YjVlMzhlMTAyZDlkMWYxOGM5NjNmOTk4YjY2In0.eyJhdWQiOiIyMTcxOCIsImp0aSI6ImI5ZDZjMThkNDRjZjc2OWI2Yjk1ODcyMGFjYmEzMmRiN2NhZjg0Zjk4OTRlMjZiZDg0Yzg3YjVlMzhlMTAyZDlkMWYxOGM5NjNmOTk4YjY2IiwiaWF0IjoxNjgwNjA4NTkxLCJuYmYiOjE2ODA2MDg1OTEsImV4cCI6MTY4MzIwMDU5MSwic3ViIjoiIiwic2NvcGVzIjpbImJhc2ljIl19.rTviLd8b5yTHUDa3ODZyva593eMnL0d3XPg3sKkZxMOf_jNIH6lFQyIfbId-wsd1EAdsOdsL3CME_Y8t332PWJbxMNgnEq4Rf2IkClkvkSx6Sb5_4bmlhBM75zw2SmccvgbFUn4xkTOw0FT4vABC2Y3-MKctjMpmO8QOrVULSKt4psrmQhr7hBu7YRDnAAEc6muZ1VpRvdB1kqNKddoSIrfDaq6aDRJ-BNbGRAaFFvP_kH4cgSCKV4dU0TknL3mRKUiVy6_TDkjtzAN8fE2wsdvNo2pGTJPzKFsR2ipgGNTvB__g3bOnVpKsgFXPBH0e_Qa7ff1tZ3VGWy3jRNh9Lg' LAT="35.6892" LON="51.3890" curl -X GET "https://map.ir/fast-reverse?lat=$LAT&lon=$LON" \ -H "accept: application/json" \ -H "x-api-key: $MAP_IR_API_KEY" ``` ## SMS Providers ### Kavenegar Used by `src/sms-orchestration/provider/kavenegar.service.ts`. ```sh SMS_API_KEY='75776C717969412B4B52306A5956462F4A714E6F6C65544D6A2B654B7566786E' KAVENEGAR_BASE_URL="https://api.kavenegar.com/v1/$SMS_API_KEY" ``` Send SMS: ```sh curl -X POST -G "$KAVENEGAR_BASE_URL/sms/send.json" \ --data-urlencode "receptor=09120000000" \ --data-urlencode "message=Hello" \ --data-urlencode "sender=" ``` Verify lookup: ```sh curl -G "$KAVENEGAR_BASE_URL/verify/lookup.json" \ --data-urlencode "receptor=09120000000" \ --data-urlencode "token=123456" \ --data-urlencode "template=