Skip to main content
POST
/
api
/
public
/
v2
/
requests
/
search
Search Request Logs
curl --request POST \
  --url https://api.promptlayer.com/api/public/v2/requests/search \
  --header 'Content-Type: application/json' \
  --header 'X-API-KEY: <x-api-key>' \
  --data '
{
  "filters": [
    {
      "field": "pl_id",
      "operator": "is",
      "value": "<string>",
      "nested_key": "<string>"
    }
  ],
  "filter_group": {
    "filters": [
      {
        "field": "pl_id",
        "operator": "is",
        "value": "<string>",
        "nested_key": "<string>"
      }
    ],
    "logic": "AND"
  },
  "q": "<string>",
  "page": 2,
  "per_page": 13,
  "sort_by": "request_start_time",
  "sort_order": "asc",
  "include_prompt_name": true
}
'
{
  "success": true,
  "items": [
    {}
  ],
  "page": 123,
  "pages": 123,
  "per_page": 123,
  "total": 123,
  "has_next": true,
  "has_prev": true,
  "next_num": 123,
  "prev_num": 123
}
Search through your logged requests programmatically using the same powerful filtering available in the PromptLayer dashboard. This is useful for:
  • Analytics & monitoring: Query requests by cost, latency, model, or status
  • Debugging: Find requests matching specific metadata, tags, or error states
  • Data export: Paginate through filtered results for downstream processing
  • Custom dashboards: Build your own views on top of PromptLayer data

Authentication

This endpoint requires API key authentication via the X-API-KEY header, or JWT authentication via the Authorization: Bearer header.
This endpoint is rate limited to 10 requests per minute. Results are capped at 25 per page.

Filters

Filters let you narrow results by any request log field. Pass them in the filters array — multiple filters are combined with AND logic.
{
  "filters": [
    { "field": "engine", "operator": "is", "value": "gpt-4o" },
    { "field": "cost", "operator": "gte", "value": 0.01 }
  ]
}

Available Fields

FieldTypeDescription
pl_ididentifierPromptLayer request ID
prompt_ididentifierAssociated prompt template ID
enginestringModel name (e.g. gpt-4o, claude-sonnet-4-20250514)
provider_typestringProvider (e.g. openai, anthropic)
input_textstringPrompt input content
output_textstringLLM output content
prompt_version_numbernumericPrompt template version
input_tokensnumericInput token count
output_tokensnumericOutput token count
costnumericRequest cost in USD
latency_msnumericLatency in milliseconds
request_start_timedatetimeWhen the request started (ISO 8601)
request_end_timedatetimeWhen the request ended (ISO 8601)
statusstatusRequest status (success, error, etc.)
is_jsonbooleanWhether output is JSON
is_tool_callbooleanWhether the request used tool calling
is_plain_textbooleanWhether output is plain text
tagsarrayTags attached to the request
metadatanestedMetadata key-value pairs
metadata_keysarrayList of metadata keys present
tool_namesarrayNames of tools used
outputnestedFlattened output key-value pairs (JSON and tool call output only)
output_keysarrayList of keys present in the flattened output
input_variablesnestedFlattened input variable key-value pairs
input_variable_keysarrayList of input variable keys
Understanding nested fields: The output, metadata, and input_variables fields are flattened from nested objects into searchable key-value pairs using dot-notation (e.g. result.status). See the Search Data Model guide for details on how different output types are indexed and when to use key_equals vs key_contains.
Input variables are only indexed if they are referenced in your prompt template. Unused input variables will not appear in search results. If you need to filter by values not in the template, attach them as metadata instead.

Operators by Field Type

OperatorDescription
isExact match
is_notNot equal
inMatches any value in a list
not_inDoes not match any value in a list
OperatorDescription
containsText contains the value (partial match)
not_containsText does not contain the value
starts_withText starts with the value
ends_withText ends with the value
OperatorDescriptionExample value
eqEqual100
neqNot equal100
gtGreater than0.01
gteGreater than or equal0.01
ltLess than1000
lteLess than or equal1000
betweenWithin a range (inclusive)[100, 500]
is_nullValue is null
is_not_nullValue is not null
OperatorDescriptionExample value
isExact match"2025-03-15T00:00:00Z"
beforeBefore this time"2025-03-15T00:00:00Z"
afterAfter this time"2025-03-14T00:00:00Z"
betweenWithin a time range["2025-03-14T00:00:00Z", "2025-03-15T00:00:00Z"]
OperatorDescription
is_trueField is true
is_falseField is false
OperatorDescriptionExample value
containsArray contains this value"production"
not_containsArray does not contain this value"test"
inArray contains any of these values["prod", "staging"]
not_inArray contains none of these values["test", "debug"]
is_emptyArray is empty
is_not_emptyArray is not empty
Nested fields store key-value pairs. Use the nested_key parameter to specify which key to filter on.
OperatorDescription
key_equalsThe value for the given key exactly matches
key_not_equalsThe value for the given key does not match
key_containsThe value for the given key contains the search term
inThe value for the given key matches any in a list
not_inThe value for the given key matches none in a list
is_emptyThe key does not exist
is_not_emptyThe key exists
Matching behavior for nested fields:
  • key_equals and key_not_equals perform exact matching, which works best with short, discrete values like IDs, status codes, and enum-like strings.
  • key_contains performs partial text matching, which is better suited for longer text values or when you only know part of the value.
If an exact match filter isn’t returning expected results, the value may be stored as a longer string internally — try key_contains instead.
{
  "filters": [
    {
      "field": "metadata",
      "operator": "key_equals",
      "value": "customer_123",
      "nested_key": "user_id"
    }
  ]
}

Complex Filters with AND/OR Logic

For more sophisticated queries, use filter_group to combine filters with AND/OR logic. Groups can be nested recursively.
{
  "filter_group": {
    "logic": "OR",
    "filters": [
      { "field": "tags", "operator": "contains", "value": "production" },
      {
        "logic": "AND",
        "filters": [
          { "field": "engine", "operator": "in", "value": ["gpt-4o", "claude-sonnet-4-20250514"] },
          { "field": "latency_ms", "operator": "gt", "value": 5000 }
        ]
      }
    ]
  }
}
You can use filters and filter_group together — they are combined with AND logic.
The q parameter performs a fuzzy prefix search across the prompt input and LLM output text. Combine it with filters to narrow results.
{
  "q": "refund policy",
  "filters": [
    { "field": "tags", "operator": "contains", "value": "customer-support" }
  ]
}

Sorting

Sort results by any of these fields:
  • request_start_time (default, descending)
  • input_tokens
  • output_tokens
  • cost
  • latency_ms
  • status
Both sort_by and sort_order must be provided together.

Examples

Find expensive requests from the last 24 hours

curl -X POST https://api.promptlayer.com/api/public/v2/requests/search \
  -H "X-API-KEY: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "filters": [
      { "field": "cost", "operator": "gte", "value": 0.10 },
      { "field": "request_start_time", "operator": "after", "value": "2025-03-14T00:00:00Z" }
    ],
    "sort_by": "cost",
    "sort_order": "desc"
  }'

Find errors on a specific prompt template

{
  "filters": [
    { "field": "prompt_id", "operator": "is", "value": 1234 },
    { "field": "status", "operator": "is", "value": "error" }
  ]
}

Search by metadata

{
  "filters": [
    {
      "field": "metadata",
      "operator": "key_equals",
      "value": "customer_123",
      "nested_key": "user_id"
    }
  ]
}

Paginate through results

{
  "filters": [
    { "field": "engine", "operator": "is", "value": "gpt-4o" }
  ],
  "page": 3,
  "per_page": 25,
  "sort_by": "request_start_time",
  "sort_order": "desc"
}

Response

{
  "success": true,
  "items": [
    {
      "id": 12345,
      "engine": "gpt-4o",
      "provider_type": "openai",
      "input_tokens": 150,
      "output_tokens": 300,
      "price": 0.005,
      "request_start_time": "2025-03-15T10:30:00",
      "request_end_time": "2025-03-15T10:30:01",
      "latency": 1.234,
      "tags_array": ["production"],
      "metadata": [{ "user_id": "customer_123" }],
      "scores": [],
      "prompt_name": "my-prompt"
    }
  ],
  "page": 1,
  "pages": 5,
  "per_page": 25,
  "total": 112,
  "has_next": true,
  "has_prev": false,
  "next_num": 2,
  "prev_num": null
}

Headers

X-API-KEY
string
required

API key for authentication.

Body

application/json

Search and filter request logs with structured filters, free-text search, sorting, and pagination.

filters
StructuredFilter · object[] | null

List of structured filters. Multiple filters are combined with AND logic.

filter_group
StructuredFilterGroup · object

Nested filter group with AND/OR logic. Use this for complex queries.

q
string | null

Free-text search query. Searches across the prompt input and LLM output text using fuzzy prefix matching.

page
integer | null

Page number for pagination. Defaults to 1.

Required range: x >= 1
per_page
integer | null

Number of results per page. Defaults to 10, maximum 25.

Required range: 1 <= x <= 25
sort_by
enum<string> | null

Field to sort results by.

Available options:
request_start_time,
input_tokens,
output_tokens,
cost,
latency_ms,
status
sort_order
enum<string> | null

Sort direction. Must be provided together with sort_by.

Available options:
asc,
desc
include_prompt_name
boolean | null

When true, includes the prompt template name in each result item. Defaults to false.

Response

Paginated list of matching request logs.

Paginated search results.

success
boolean

Indicates the request was successful.

items
object[]

List of matching request log summaries.

page
integer

Current page number.

pages
integer

Total number of pages.

per_page
integer

Number of results per page.

total
integer

Total number of matching results.

has_next
boolean

Whether there are more pages after the current one.

has_prev
boolean

Whether there are pages before the current one.

next_num
integer | null

Next page number, or null if on the last page.

prev_num
integer | null

Previous page number, or null if on the first page.