> ## Documentation Index
> Fetch the complete documentation index at: https://axiom.co/docs/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://axiom.co/docs/feedback

```json
{
  "path": "/apl/scalar-functions/string-functions/indexof",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# indexof

> This page explains how to use the indexof function in APL.

The `indexof` function reports the zero-based index of the first occurrence of a specified string within an input string. Use this function to find the position of substrings, validate string formats, or extract parts of strings based on delimiter positions.

## For users of other query languages

If you come from other query languages, this section explains how to adjust your existing queries to achieve the same results in APL.

<AccordionGroup>
  <Accordion title="Splunk SPL users">
    In Splunk SPL, you might use `searchmatch` or string manipulation. APL's `indexof` provides a direct way to find substring positions.

    <CodeGroup>
      ```sql Splunk example theme={null}
      | eval pos=if(match(field, "search"), strpos(field, "search"), -1)
      ```

      ```kusto APL equivalent theme={null}
      ['sample-http-logs']
      | extend pos = indexof(field, 'search')
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="ANSI SQL users">
    In ANSI SQL, you use `POSITION()` or `INSTR()` to find substring positions. APL's `indexof` provides similar functionality with additional parameters.

    <CodeGroup>
      ```sql SQL example theme={null}
      SELECT POSITION('search' IN field) - 1 AS pos FROM logs;
      ```

      ```kusto APL equivalent theme={null}
      ['sample-http-logs']
      | extend pos = indexof(field, 'search')
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

## Usage

### Syntax

```kusto theme={null}
indexof(source, lookup, start_index, length, occurrence)
```

### Parameters

| Name         | Type   | Required | Description                                                                   |
| ------------ | ------ | -------- | ----------------------------------------------------------------------------- |
| source       | string | Yes      | The input string to search within.                                            |
| lookup       | string | Yes      | The string to search for.                                                     |
| start\_index | int    | No       | The position to start searching from (default: 0).                            |
| length       | int    | No       | Number of character positions to examine. Use -1 for unlimited (default: -1). |
| occurrence   | int    | No       | The occurrence number to find (default: 1 for first occurrence).              |

### Returns

Returns the zero-based index position of the first occurrence of the lookup string, or -1 if not found.

## Use case examples

<Tabs>
  <Tab title="Log analysis">
    Find the position of API version indicators in URIs to categorize and analyze API usage patterns.

    **Query**

    ```kusto theme={null}
    ['sample-http-logs']
    | extend api_pos = indexof(uri, '/api/')
    | where api_pos >= 0
    | extend has_version = indexof(uri, '/v', api_pos)
    | project _time, uri, api_pos, has_version, method, status
    | limit 10
    ```

    [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%20%7C%20extend%20api_pos%20%3D%20indexof\(uri%2C%20%27%2Fapi%2F%27\)%20%7C%20where%20api_pos%20%3E%3D%200%20%7C%20extend%20has_version%20%3D%20indexof\(uri%2C%20%27%2Fv%27%2C%20api_pos\)%20%7C%20project%20_time%2C%20uri%2C%20api_pos%2C%20has_version%2C%20method%2C%20status%20%7C%20limit%2010%22%7D)

    **Output**

    | \_time               | uri            | api\_pos | has\_version | method | status |
    | -------------------- | -------------- | -------- | ------------ | ------ | ------ |
    | 2024-11-06T10:00:00Z | /api/v2/users  | 0        | 4            | GET    | 200    |
    | 2024-11-06T10:01:00Z | /api/products  | 0        | -1           | GET    | 200    |
    | 2024-11-06T10:02:00Z | /api/v1/orders | 0        | 4            | POST   | 201    |

    This query finds the position of API indicators in URIs, helping identify versioned versus unversioned API endpoints.
  </Tab>

  <Tab title="OpenTelemetry traces">
    Locate service name delimiters to extract service identifiers from composite names.

    **Query**

    ```kusto theme={null}
    ['otel-demo-traces']
    | extend dash_pos = indexof(['service.name'], '-')
    | where dash_pos >= 0
    | extend service_prefix = substring(['service.name'], 0, dash_pos)
    | summarize span_count = count() by service_prefix
    | sort by span_count desc
    | limit 10
    ```

    [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D%20%7C%20extend%20dash_pos%20%3D%20indexof\(%5B%27service.name%27%5D%2C%20%27-%27\)%20%7C%20where%20dash_pos%20%3E%3D%200%20%7C%20extend%20service_prefix%20%3D%20substring\(%5B%27service.name%27%5D%2C%200%2C%20dash_pos\)%20%7C%20summarize%20span_count%20%3D%20count\(\)%20by%20service_prefix%20%7C%20sort%20by%20span_count%20desc%20%7C%20limit%2010%22%7D)

    **Output**

    | service\_prefix | span\_count |
    | --------------- | ----------- |
    | otel            | 8765        |
    | service         | 4321        |
    | app             | 2345        |

    This query uses `indexof` to find delimiter positions in service names, enabling extraction of service prefixes for grouping and analysis.
  </Tab>

  <Tab title="Security logs">
    Detect SQL injection attempts by finding the position of SQL keywords in URIs.

    **Query**

    ```kusto theme={null}
    ['sample-http-logs']
    | extend union_pos = indexof(tolower(uri), 'union'),
             select_pos = indexof(tolower(uri), 'select'),
             drop_pos = indexof(tolower(uri), 'drop')
    | where union_pos >= 0 or select_pos >= 0 or drop_pos >= 0
    | project _time, uri, union_pos, select_pos, drop_pos, id, status, ['geo.country']
    | sort by _time desc
    | limit 10
    ```

    [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%20%7C%20extend%20union_pos%20%3D%20indexof\(tolower\(uri\)%2C%20%27union%27\)%2C%20select_pos%20%3D%20indexof\(tolower\(uri\)%2C%20%27select%27\)%2C%20drop_pos%20%3D%20indexof\(tolower\(uri\)%2C%20%27drop%27\)%20%7C%20where%20union_pos%20%3E%3D%200%20or%20select_pos%20%3E%3D%200%20or%20drop_pos%20%3E%3D%200%20%7C%20project%20_time%2C%20uri%2C%20union_pos%2C%20select_pos%2C%20drop_pos%2C%20id%2C%20status%2C%20%5B%27geo.country%27%5D%20%7C%20sort%20by%20_time%20desc%20%7C%20limit%2010%22%7D)

    **Output**

    | \_time               | uri                    | union\_pos | select\_pos | drop\_pos | id      | status | geo.country |
    | -------------------- | ---------------------- | ---------- | ----------- | --------- | ------- | ------ | ----------- |
    | 2024-11-06T10:00:00Z | /api?id=1'union select | -1         | 11          | -1        | user123 | 403    | Unknown     |
    | 2024-11-06T10:01:00Z | /search?q=drop table   | -1         | -1          | 10        | user456 | 403    | Russia      |

    This query identifies potential SQL injection attempts by finding the position of SQL keywords in URIs, helping security teams detect and respond to attacks.
  </Tab>
</Tabs>

## List of related functions

* [substring](/apl/scalar-functions/string-functions/substring): Extracts a substring from a source string. Use this together with indexof to extract parts of strings based on found positions.
* [strlen](/apl/scalar-functions/string-functions/strlen): Returns the length of a string. Use this with indexof to calculate positions relative to string length.
* [extract](/apl/scalar-functions/string-functions/extract): Extracts substrings using regular expressions. Use this when you need pattern matching instead of simple substring positions.
* [split](/apl/scalar-functions/string-functions/split): Splits strings by delimiters. Use this when you want to tokenize rather than find positions.
