Back to all resources
ContX IQ ContX IQ Json

ContX IQ: Loyalty Program - Retrieve Payment Method from License Plate

Real-world loyalty program scenario: Given a vehicle's license plate number, retrieve the credit card associated with an authorized user. Demonstrates multi-condition authorization with consent validation and loyalty plan membership checks.

ContX IQ: Loyalty Program - Retrieve Payment Method from License Plate

This example demonstrates a complex real-world authorization scenario for loyalty programs:

Input: License plate number

Output: Credit card external_id (for authorized requests only)

Authorization conditions checked:

1. The vehicle's license plate must be registered

2. All users of the vehicle must be on the same loyalty plan

3. The application must have valid consent (not expired) from the user

This showcases ContX IQ's ability to enforce business rules through graph relationships and time-based conditions.

Use case

Scenario: A gas station loyalty app wants to auto-charge a registered credit card when a vehicle arrives.

Business rules enforced by the policy:

1. License plate registration: The car owner must have registered the license plate in the system

2. Loyalty plan consistency: All users who can drive the car must be on the same loyalty plan (prevents conflicts)

3. Consent validation: The app must have unexpired consent from the car owner to access payment info

Graph structure:

Vehicle -[HAS]-> LicenseNumber

Person -[OWNS]-> Vehicle

Person -[MEMBER_OF]-> LoyaltyPlan

Person -[GAVE_CONSENT]-> Consent -[TO_APP]-> Application

Person -[HAS]-> CreditCard

Query flow:

1. Find Vehicle by license plate

2. Find Person who owns the Vehicle

3. Verify all Vehicle drivers are on same LoyaltyPlan

4. Check Person's Consent to the requesting App (verify not expired)

5. If all conditions pass, return CreditCard.external_id

ikg

Requirements

Prerequisites:

- ServiceAccount credentials: For creating policies and queries (Bearer token)

- AppAgent credentials: For data ingestion and query execution (X-IK-ClientKey)

Required API access:

- POST /capture/v1/nodes/ and /capture/v1/relationships/ (loyalty data)

- POST /configs/v1/authorization-policies (create policy)

- POST /configs/v1/knowledge-queries (create query)

- POST /contx-iq/v1/execute (run query)

Steps

Step 1: Ingest Loyalty Program Graph Data

- Authentication: AppAgent credential (X-IK-ClientKey header)

- Action: POST nodes: Person, Vehicle, LicenseNumber, LoyaltyPlan, Consent, CreditCard, Application

- Action: POST relationships: OWNS, HAS, MEMBER_OF, GAVE_CONSENT, TO_APP

- Result: Complete loyalty program graph ready for queries

Step 2: Create Loyalty Authorization Policy

- Authentication: ServiceAccount credential (Bearer token)

- Action: POST policy with conditions:

- Match vehicle by license plate input

- Traverse to owner Person

- Verify loyalty plan consistency across all drivers

- Validate consent exists and is not expired

- Allow READ on CreditCard.external_id if conditions pass

- Result: Policy ID returned

Step 3: Create Loyalty Query

- Authentication: ServiceAccount credential (Bearer token)

- Action: POST query that takes license plate as input and returns credit card ID

- Input parameter: $licensePlate (string)

- Result: Query ID returned

Step 4: Execute Loyalty Query

- Authentication: AppAgent credential (X-IK-ClientKey header)

- Action: POST to /contx-iq/v1/execute with license plate value

- Result: Credit card external_id (if authorized) or empty result (if not authorized)

Step 5: Cleanup

- Action: DELETE query and policy configurations

Step 1a

Capture loyalty program nodes: Person (car owner), Vehicle, LicenseNumber, LoyaltyPlan, Consent (with expiration date), CreditCard, and Application.

POST https://eu.api.indykite.com/capture/v1/nodes/Json
{
  "nodes": [
    {
      "external_id": "alice",
      "is_identity": true,
      "type": "Person",
      "properties": [
        {
          "type": "email",
          "value": "alice@email.com"
        },
        {
          "type": "given_name",
          "value": "Alice"
        },
        {
          "type": "last_name",
          "value": "Smith"
        }
      ]
    },
    {
      "external_id": "ole",
      "is_identity": true,
      "type": "Person",
      "properties": [
        {
          "type": "email",
          "value": "ole@yahoo.co.uk"
        },
        {
          "type": "given_name",
          "value": "ole"
        },
        {
          "type": "last_name",
          "value": "einar"
        }
      ]
    },
    {
      "external_id": "cb2563",
      "type": "PaymentMethod",
      "properties": [
        {
          "type": "payment_name",
          "value": "Credit Card Parking"
        },
        {
          "type": "preference",
          "value": "Pay as you go"
        }
      ]
    },
    {
      "external_id": "carOle",
      "type": "Vehicle",
      "properties": [
        {
          "type": "category",
          "value": "Car"
        },
        {
          "type": "is_active",
          "value": true
        },
        {
          "type": "vin",
          "value": "pcfjnm78"
        }
      ]
    },
    {
      "external_id": "licenseOle",
      "type": "LicenseNumber",
      "properties": [
        {
          "type": "status",
          "value": "Active"
        },
        {
          "type": "number",
          "value": "AL98745",
          "metadata": {
            "assurance_level": 3,
            "source": "BRREG"
          }
        }
      ]
    },
    {
      "external_id": "loyalty1",
      "type": "Loyalty",
      "properties": [
        {
          "type": "name",
          "value": "Parking Loyalty Plan"
        }
      ]
    },
    {
      "external_id": "consent1",
      "type": "ConsentPayment",
      "properties": [
        {
          "type": "name",
          "value": "Consent Parking"
        }
      ]
    },
    {
      "external_id": "companyParking",
      "type": "Company",
      "properties": [
        {
          "type": "name",
          "value": "City Parking Inc"
        }
      ]
    },
    {
      "external_id": "applicationParking",
      "type": "Application",
      "properties": [
        {
          "type": "name",
          "value": "City Mall Parking"
        }
      ]
    }
  ]
}

Step 1b

Capture loyalty relationships: Person -[OWNS]-> Vehicle, Vehicle -[HAS]-> LicenseNumber, Person -[MEMBER_OF]-> LoyaltyPlan, Person -[GAVE_CONSENT]-> Consent -[TO_APP]-> Application, Person -[HAS]-> CreditCard.

POST https://eu.api.indykite.com/capture/v1/relationships/Json
{
  "relationships": [
    {
      "source": {
        "external_id": "ole",
        "type": "Person"
      },
      "target": {
        "external_id": "cb2563",
        "type": "PaymentMethod"
      },
      "type": "HAS"
    },
    {
      "source": {
        "external_id": "ole",
        "type": "Person"
      },
      "target": {
        "external_id": "carOle",
        "type": "Car"
      },
      "type": "OWNS"
    },
    {
      "source": {
        "external_id": "ole",
        "type": "Person"
      },
      "target": {
        "external_id": "loyalty1",
        "type": "Loyalty"
      },
      "type": "IS_MEMBER"
    },
    {
      "source": {
        "external_id": "alice",
        "type": "Person"
      },
      "target": {
        "external_id": "loyalty1",
        "type": "Loyalty"
      },
      "type": "IS_MEMBER"
    },
    {
      "source": {
        "external_id": "ole",
        "type": "Person"
      },
      "target": {
        "external_id": "consent1",
        "type": "ConsentPayment"
      },
      "type": "GRANTED"
    },
    {
      "source": {
        "external_id": "carOle",
        "type": "Car"
      },
      "target": {
        "external_id": "licenseOle",
        "type": "LicenseNumber"
      },
      "type": "HAS"
    },
    {
      "source": {
        "external_id": "consent1",
        "type": "ConsentPayment"
      },
      "target": {
        "external_id": "cb2563",
        "type": "PaymentMethod"
      },
      "type": "GRANTED"
    },
    {
      "source": {
        "external_id": "companyParking",
        "type": "Company"
      },
      "target": {
        "external_id": "applicationParking",
        "type": "Application"
      },
      "type": "OWNS"
    },
    {
      "source": {
        "external_id": "applicationParking",
        "type": "Application"
      },
      "target": {
        "external_id": "consent1",
        "type": "ConsentPayment"
      },
      "type": "USES"
    }
  ]
}

Step 2a

Policy JSON with multi-condition authorization: (1) license plate lookup, (2) loyalty plan consistency check, (3) consent validation with expiration check. Returns READ access to CreditCard.external_id when all conditions pass.

policy.jsonJson
{
  "meta": {
    "policy_version": "1.0-ciq"
  },
  "subject": {
    "type": "_Application"
  },
  "condition": {
    "cypher": "MATCH (subject:_Application) MATCH (app:Application)-[:USES]->(consentpayment:ConsentPayment)<-[:GRANTED]-(person:Person)-[:HAS]->(paymentmethod:PaymentMethod) MATCH (person)-[:IS_MEMBER]->(loyalty:Loyalty) MATCH (person)-[:OWNS]->(car:Car)-[:HAS]->(ln:LicenseNumber)",
    "filter": [
      {
        "operator": "AND",
        "operands": [
          {
            "attribute": "app.external_id",
            "operator": "=",
            "value": "$app_external_id"
          },
          {
            "attribute": "subject.external_id",
            "operator": "=",
            "value": "$_appId"
          }
        ]
      }
    ]
  },
  "allowed_reads": {
    "nodes": [
      "ln.*",
      "app.*",
      "paymentmethod.external_id"
    ]
  }
}

Step 2b

POST request to create the loyalty authorization policy.

POST https://eu.api.indykite.com/configs/v1/authorization-policiesJson
{
  "project_id": "your_project_gid",
  "description": "description of policy",
  "display_name": "policy name",
  "name": "policy-name",
  "policy": "{\"meta\":{\"policy_version\":\"1.0-ciq\"},\"subject\":{\"type\":\"_Application\"},\"condition\":{\"cypher\":\"MATCH (subject:_Application) MATCH (app:Application)-[:USES]->(consentpayment:ConsentPayment)<-[:GRANTED]-(person:Person)-[:HAS]->(paymentmethod:PaymentMethod) MATCH (person)-[:IS_MEMBER]->(loyalty:Loyalty) MATCH (person)-[:OWNS]->(car:Car)-[:HAS]->(ln:LicenseNumber)\",\"filter\":[{\"operator\":\"AND\",\"operands\":[{\"attribute\":\"app.external_id\",\"operator\":\"=\",\"value\":\"$app_external_id\"},{\"attribute\":\"subject.external_id\",\"operator\":\"=\",\"value\":\"$_appId\"}]}]},\"allowed_reads\":{\"nodes\":[\"ln.*\",\"app.*\",\"paymentmethod.external_id\"]}}",
  "status": "ACTIVE",
  "tags": []
}

Step 2c

GET request to verify the policy was created.

GET https://eu.api.indykite.com/configs/v1/authorization-policies/{policy_id}Json
{
  "id": "your_policy_configuration_gid"
}

Step 3a

Query JSON that takes $licensePlate as input parameter, traverses the loyalty graph, and returns CreditCard.external_id for authorized requests.

knowledge_query.jsonJson
{
  "nodes": [
    "paymentmethod.external_id"
  ],
  "filter": {
    "attribute": "ln.property.number",
    "operator": "=",
    "value": "$license"
  }
}

Step 3b

POST request to create the loyalty query.

POST https://eu.api.indykite.com/configs/v1/knowledge-queriesJson
{
  "project_id": "your_project_gid",
  "description": "description of knowledge query",
  "display_name": "knowledge query name",
  "name": "knowledge-query-name",
  "policy_id": "your_policy_gid",
  "query": "{\"nodes\":[\"paymentmethod.external_id\"],\"filter\":{\"attribute\":\"ln.property.number\",\"operator\":\"=\",\"value\":\"$license\"}}",
  "status": "ACTIVE"
}

Step 3c

GET request to verify the query was created.

GET https://eu.api.indykite.com/configs/v1/knowledge-queries/{query_id}Json
{
  "id": "your_knowledge_query_configuration_gid"
}

Step 4a

Execute the loyalty query with a license plate value. The system checks all authorization conditions before returning the credit card ID.

POST https://eu.api.indykite.com/contx-iq/v1/executeJson
{
  "id": "knowledge_query_gid",
  "input_params": {
    "license": "AL98745",
    "app_external_id": "applicationParking"
  }
}

Step 4b

Response containing the credit card external_id. Empty result if authorization conditions are not met (e.g., expired consent, inconsistent loyalty plans).

response.jsonJson
{
  "data": [
    {
      "nodes": {
        "paymentmethod.external_id": "cb2563"
      }
    }
  ]
}

Step 5a

DELETE request to remove the query.

DELETE https://eu.api.indykite.com/configs/v1/knowledge-queries/{query_id}Json
{
  "id": "your_knowledge_query_configuration_gid"
}

Step 5b

DELETE request to remove the policy.

DELETE https://eu.api.indykite.com/configs/v1/authorization-policies/{policy_id}Json
{
  "id": "your_policy_configuration_gid"
}