πŸ“˜ 2025 Report:Mexico Economic Review 2025 β€” outlook, charts, and sector signalsRead

    Code Samples

    Python, Node.js & cURL β€” All three integration models

    Setup

    import requests
    
    BASE_URL = "https://service.criskco.com/apiservice.svc"
    HEADERS = {
        "apiId": "YOUR_API_ID",
        "apiKey": "YOUR_API_KEY",
        "Content-Type": "application/json",
        "Accept-Encoding": "gzip, deflate"
    }

    Model A β€” Approve API (Full Control)

    Step 1 β€” Validate RFC

    def validate_rfc(rfc, name=None, postal=None):
        params = {"rfc": rfc}
        if name:
            params["name"] = name
        if postal:
            params["postal"] = postal
    
        r = requests.get(f"{BASE_URL}/ValidateRFC", headers=HEADERS, params=params)
        return r.json()
    
    result = validate_rfc("GAPXXXXXXXXX", name="GAP", postal="06600")
    if not result["Success"]:
        raise Exception(f"RFC invalid: {result['message']}")
    print(result["message"])

    Step 2 β€” Onboard the Applicant

    def onboard_applicant(rfc, ciec_password, email, ref_id=""):
        payload = {
            "IsAgreeTerms": True,
            "DateAgreeTerms": "2026-03-24",
            "VersionAgreeTerms": "1",
            "Email": email,
            "User": rfc,
            "Password": ciec_password,
            "RefApplicantId": ref_id
        }
        r = requests.post(
            f"{BASE_URL}/OnboardingSatIntegration",
            headers=HEADERS, json=payload
        )
        return r.json()
    
    result = onboard_applicant(
        rfc="GAPXXXXXXXXX",
        ciec_password="CIEC_PASSWORD",
        email="contact@empresa.com",
        ref_id="loan-app-00482"
    )

    Step 3 β€” Poll for Status and Get applicantId

    import time
    
    def wait_for_applicant(tax_id, max_attempts=10, interval=5):
        for _ in range(max_attempts):
            r = requests.get(
                f"{BASE_URL}/get-applicants",
                headers=HEADERS,
                params={"taxId": tax_id, "onboardingStatus": "true"}
            )
            applicants = r.json().get("applicant", [])
            if applicants and applicants[0].get("status") == "Available":
                return applicants[0]["applicantId"]
            time.sleep(interval)
        raise TimeoutError("Applicant not Available within timeout")
    
    applicant_id = wait_for_applicant("GAPXXXXXXXXX")

    Model B β€” Hosted Page

    Redirect the applicant to CRiskCo's onboarding page. No API call needed for onboarding.

    Option 1 β€” General onboarding

    Standard page β€” the applicant enters your reference code during the flow:

    https://app.criskco.com/onboarding/#!/app/referrer-es

    Option 2 β€” White-label onboarding

    Requires white-label provisioning with CRiskCo:

    https://yourbrand.criskco.com/onboarding/#!/app/

    Then poll using refApplicantId:

    def get_applicant_by_ref(ref_id):
        r = requests.get(
            f"{BASE_URL}/get-applicants",
            headers=HEADERS,
            params={"refApplicantId": ref_id, "onboardingStatus": "true"}
        )
        applicants = r.json().get("applicant", [])
        return applicants[0] if applicants else None
    
    applicant = get_applicant_by_ref("loan-app-00482")
    if applicant and applicant["status"] == "Available":
        applicant_id = applicant["applicantId"]

    Model C β€” Webhooks

    Register Your Webhook

    def register_webhook(callback_url):
        r = requests.post(
            f"{BASE_URL}/Subscriptions",
            headers=HEADERS,
            json={"CallbackUrl": callback_url}
        )
        result = r.json()
        if result.get("success"):
            sub = result["ApiSubscriptionData"]
            print(f"Subscription {sub['SubscriptionId']} created: {sub['Active']}")
        return result
    
    register_webhook("https://yourdomain.com/webhooks/criskco")

    Handle Incoming Webhook Events

    from flask import Flask, request, jsonify
    import json, requests as req
    
    app = Flask(__name__)
    
    @app.route("/webhooks/criskco", methods=["GET"])
    def webhook_validation():
        return "", 200  # Respond within 2 seconds
    
    @app.route("/webhooks/criskco", methods=["POST"])
    def webhook_handler():
        event = request.json
        applicant_id = event.get("applicantId")
        file_type = event.get("FileType")
    
        if file_type == "JSON":
            payload = json.loads(event.get("APIResponse", "{}"))
        elif file_type == "JSON_LINK":
            url = event["DownloadUrlList"][0]
            payload = req.get(url).json()
    
        if payload.get("onboardingStatus") == "Available":
            print(f"Applicant {applicant_id} ready")
            blacklists = payload.get("blackLists", [])
            if blacklists:
                print(f"WARNING: Blacklist flags: {blacklists}")
        return jsonify({"received": True}), 200

    Manage Subscriptions

    List all active subscriptions and delete by ID.

    # List all subscriptions
    def list_subscriptions():
        r = requests.get(f"{BASE_URL}/Subscriptions", headers=HEADERS)
        return r.json()
    
    # Delete a subscription by ID
    def delete_subscription(subscription_id):
        r = requests.delete(
            f"{BASE_URL}/Subscriptions/{subscription_id}",
            headers=HEADERS
        )
        return r.json()

    SAT Compliance Data

    Tax Status

    def get_tax_status(tax_id):
        r = requests.get(
            f"{BASE_URL}/GetCompanyTaxStatus",
            headers=HEADERS,
            params={"taxId": tax_id}
        )
        company = r.json()["CompanyTaxStatus"][0]
        print(f"Status: {company['PayingTax']}")
        if company["PayingTax"] == "NEGATIVO":
            for ob in company.get("CompanyObligationsList", []):
                print(f"  Obligation: {ob['Obligation']} ({ob['Month']}/{ob['Year']})")
        return company

    Historical FinScore

    def get_finscore_history(tax_id):
        r = requests.get(
            f"{BASE_URL}/GetHistoricalFinscore",
            headers=HEADERS,
            params={"taxId": tax_id}
        )
        scores = r.json().get("HistoricalFinscores", [])
        for s in sorted(scores, key=lambda x: (x["Year"], x["Month"])):
            print(f"{s['Year']}-{s['Month']:02d}: {s['FinScore']}")
        return scores

    Financial Data

    All Financials in One Call

    def get_all_financials(applicant_id):
        r = requests.post(
            f"{BASE_URL}/grouping/applicant-financials",
            headers=HEADERS,
            json={"applicantId": applicant_id, "csvInJson": False}
        )
        return r.json()
    # Returns: standardized reports, raw data, documents, analytics

    AR Invoices with Date Filter

    Query sales invoices filtered by date range for revenue analysis.

    def get_ar_invoices(applicant_id, from_date=None, to_date=None):
        params = {}
        if from_date:
            params["fromDate"] = from_date
        if to_date:
            params["toDate"] = to_date
    
        r = requests.post(
            f"{BASE_URL}/ar-transactions/invoices",
            headers=HEADERS,
            json={"applicantId": applicant_id},
            params=params
        )
        return r.json()
    
    # Example: last 12 months of AR invoices
    invoices = get_ar_invoices("1000143693", from_date="2025-03-01", to_date="2026-03-01")

    Monitoring & Bulk Validation

    Trigger Monitoring Refresh

    def trigger_monitoring(applicant_id):
        r = requests.post(
            f"{BASE_URL}/RequestMonitoring",
            headers=HEADERS,
            json={"applicantId": applicant_id, "Source": "API"}
        )
        result = r.json()
        print(f"Monitoring triggered: {result['success']}")
        return result

    Bulk RFC Validation

    def validate_rfc_bulk(rfc_list):
        file_content = "\n".join(rfc_list).encode("utf-8")
        headers_no_ct = {k: v for k, v in HEADERS.items() if k != "Content-Type"}
        r = requests.post(
            f"{BASE_URL}/ValidateRFCBulk",
            headers=headers_no_ct,
            files={"file": ("rfcs.txt", file_content, "text/plain")}
        )
        return r.text  # Results per RFC