ApiCall lets you declare API call parameters and response extraction directly in Gherkin, without writing HTTP request code. It supports both DataTable and JSON formats.
When (UID="$Alice.id") create todo, call JSON: """json { >todo1.id: <todoId, "title": "Buy milk" } """
Both produce the same result:
Use $Alice.id as the caller identity (Bearer Token)
Call the API with summary "create todo" in the API Spec
Send title: Buy milk as the Request Body
Extract the todoId field from the response and store it in variable todo1.id
JSON format note: Symbol system expressions ($ variables, & CAS constraints, @ time symbols, >/< extraction keys) must NOT be placed inside JSON string quotes "", otherwise they are treated as plain strings.
{ "title": $todo1.title } // ✅ Correct: symbol outside quotes{ "title": "$todo1.title" } // ❌ Wrong: symbol wrapped in quotes, treated as plain string
DataTable field names support special prefixes to specify parameter types:
Prefix
Purpose
Example
(none)
Request Body field; if the field name also exists as a Path/Query/Header parameter in the API Spec, it is automatically routed to the matching position (syntax sugar, equivalent to also writing P:/Q:/H:)
title, todoId
P:
Path parameter
P:todoId → replaces {todoId} in URL
Q:
Query parameter
Q:page → ?page=value
H:
Request Header
H:X-Trace-Id
B:
Explicitly mark entire Request Body (bare value, array, or object)
B: → cell value becomes entire body
>
Store into variable — defines the variable name to save the response value
>todo1.id
<
Extract from response — specifies the source field in the response JSON
<todoId
<H:
Extract from response Header — specifies the source header field
<H:Location
<B:
Extract from response Body (bare value) — extracts entire response body
The ApiCall instruction identifies the API to call using the summary field. This design allows test files to use business language rather than technical URL paths.
Each API operation's summary must be unique across the entire API Spec:
# ✅ Correct: summaries are distinct/todos: post: summary: create todo get: summary: list todos/todos/{id}: get: summary: get todo put: summary: update todo delete: summary: delete todo# ❌ Wrong: duplicate summaries cause identification failure/todos: get: summary: get todo/todos/{id}: get: summary: get todo # Duplicate!
When a Body field name matches a Path/Query/Header parameter name in the API Spec, the value is sent as a Body field and also automatically routed to the matching parameter position, without requiring a P: or Q: prefix:
# todoId is both Body and Path parameter → automatically routes to P:todoId| todoId | title || 123 | Buy soy milk |
B: also works for object bodies, providing visual separation between parameters and body (the implicit body rule for non-prefixed keys remains backward-compatible):
(UID="...") specifies the caller identity, and the framework automatically injects the corresponding Bearer Token:
# Use variable as callerWhen (UID="$Alice.id") list todos, call table: | Q:status | | active |# No authentication requiredWhen (No Actor) health check, call table: | |
Even when there are no parameters, an empty DataTable is required to satisfy the syntax.
When your test goal is to verify that the API rejects missing/invalid required parameters, you can add @allow-missing-parameters on an Example (or Scenario). This skips the required-parameter check for that scenario, while keeping other contract checks enabled.
Feature: Query API parameter validation Rule: Required parameter validation rules Example: Should succeed with complete parameters When (UID="$Alice.id") query data, call table: | Q:startDate | Q:endDate | Q:pageNo | Q:pageSize | | 2024-01-01 | 2024-01-31 | 1 | 10 | Then query data(200) response, with table: | success | | true | @allow-missing-parameters Example: Should fail when required parameter startDate is missing When (UID="$Alice.id") query data, call table: | Q:endDate | Q:pageNo | Q:pageSize | | 2024-01-31 | 1 | 10 | Then query data(400) response, with table: | errorCode | | MISSING_REQUIRED_PARAMETER |
Feature: Todo Management Background: Given current time is "2026-01-27T10:00:00" # EntitySetup instruction — prepare test data (see EntitySetup docs) # >Alice.id / <userId: extract userId from response into Alice.id variable Given prepare a user, with table: | >Alice.id | name | email | status | | <userId | Alice | alice@example.com | ACTIVE | Example: Create and update a todo # (No Actor): API call without authentication # >AliceToken / <token: extract token from response When (No Actor) user login, call table: | >AliceToken | email | password | | <token | alice@example.com | password123 | # (UID="$Alice.id"): call as Alice, Bearer Token injected automatically When (UID="$Alice.id") create todo, call table: | >todo1.id | title | | <todoId | Buy milk | # P: prefix for Path parameter; $todo1.id references a previously extracted variable When (UID="$Alice.id") update todo, call table: | P:todoId | title | | $todo1.id | Buy soy milk | # ResponseValidate instruction — verify response (see ResponseValidate docs) Then update todo(200) response, with table: | todoId | title | updatedAt | | $todo1.id | Buy soy milk | &sameTime("2026-01-27T10:00:00") |