> ## Documentation Index
> Fetch the complete documentation index at: https://docs.restate.dev/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://docs.restate.dev/feedback

```json
{
  "path": "/services/invocation/http",
  "feedback": "Description of the issue"
}
```

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

</AgentInstructions>

# HTTP

> Learn how to invoke Restate services over HTTP.

An invocation is a request to execute a handler.
You can invoke handlers over HTTP with or without waiting for a response, and with or without an idempotency key.

Make sure to first [register the handler](/services/versioning) you want to invoke.

The [UI](/installation#restate-ui) helps you with invoking your services.
Open the UI at port 9070, register your service, click on the service, open the playground, and invoke your handlers from there.

<Info>
  Each invocation has its own unique ID and lifecycle.
  Have a look at [managing invocations](/services/invocation/managing-invocations) to learn how to manage the lifecycle of an invocation.
</Info>

## Request-response calls

You can invoke services over HTTP 1.1 or higher.
Request/response bodies should be encoded as JSON.

Invoking `myHandler` of `myService` as follows:

```shell theme={null}
curl localhost:8080/MyService/myHandler \
  --json '{"name": "Mary", "age": 25}'
```

Invoke `myHandler` of `myVirtualObject` for `myObjectKey` as follows:

```shell theme={null}
curl localhost:8080/MyVirtualObject/myObjectKey/myHandler \
  --json '{"name": "Mary", "age": 25}'
```

Call the `run` handler of the `MyWorkflow` as follows:

```shell theme={null}
curl localhost:8080/MyWorkflow/myWorkflowId/run \
  --json '{"name": "Mary", "age": 25}'
```

A workflow can be submitted only once. Resubmission of the same workflow will fail with "Previously accepted". The invocation ID can be found in the request header `x-restate-id`.

Follow the same pattern for calling the other handlers of the workflow.

<Note title="Restate as proxy">
  Note that all invocations go first via the Restate Server. The server then forwards the request to the appropriate service.
  Therefore, `localhost:8080` refers to ingress port of the Restate Server, not the service instance.
</Note>

## Sending messages

If you do not want to wait for the response, you can also send a message by adding `/send` to the URL path:

```shell theme={null}
curl localhost:8080/MyService/myHandler/send \
  --json '{"name": "Mary", "age": 25}'
```

Example output:

```json theme={null}
{"invocationId":"inv_1aiqX0vFEFNH1Umgre58JiCLgHfTtztYK5","status":"Accepted"}
```

The response contains the [Invocation ID](#invocation-identifier).
You can use this identifier [to cancel](#cancelling-invocations) or [kill the invocation](#killing-invocations).

## Delayed messages

You can **delay the message** by adding a delay request parameter in ISO8601 notation or using [humantime format](https://docs.rs/humantime/latest/humantime/):

<CodeGroup>
  ```shell humantime theme={null}
  curl "localhost:8080/MyService/myHandler/send?delay=10s" \
      --json '{"name": "Mary", "age": 25}'
  ```

  ```shell ISO8601 theme={null}
  curl "localhost:8080/MyService/myHandler/send?delay=PT10S" \
      --json '{"name": "Mary", "age": 25}'
  ```
</CodeGroup>

<Note title="Not supported for workflows">
  You cannot yet use this feature for workflows.
  Workflows can only be scheduled with a delay from within another Restate handler ([TS](/develop/ts/service-communication#delayed-calls)/[Java/Kotlin](/develop/java/service-communication#delayed-calls)).
</Note>

## Using an idempotency key

You can send requests to Restate providing an idempotency key, through the [`Idempotency-Key` header](https://datatracker.ietf.org/doc/draft-ietf-httpapi-idempotency-key-header/):

```shell theme={null}
curl localhost:8080/MyService/myHandler \
  -H 'idempotency-key: ad5472esg4dsg525dssdfa5loi' \
  --json '{"name": "Mary", "age": 25}'
```

After the invocation completes, Restate persists the response for a retention period of one day (24 hours).
If you re-invoke the service with the same idempotency key within 24 hours, Restate sends back the same response and doesn't re-execute the request to the service.

Check out the [service configuration docs](/services/configuration) to tune the retention time.

<Tip title="Make any service call idempotent with Restate">
  With Restate and an idempotency key, you can make any service call idempotent, without any extra code or setup.
  This is a very powerful feature to ensure that your system stays consistent and doesn't perform the same operation multiple times.
</Tip>

## Cancel

You can cancel an invocation as follows:

```shell curl theme={null}
curl -X PATCH http://localhost:9070/invocations/inv_1gdJBtdVEcM942bjcDmb1c1khoaJe11Hbz/cancel
```

<Info>
  [Read the detailed docs on cancelling invocations](/services/invocation/managing-invocations#cancel)
</Info>

## Attach to an invocation

Restate allows you to retrieve the result of workflows and invocations with an idempotency key.
There are two options:

* To **attach** to an invocation or workflow and wait for it to finish, use `/attach`.
* To **peek at the output** of an invocation or workflow, use `/output`. This will return:
  * `{"message":"not ready"}` for ongoing workflows
  * The result for finished workflows
  * `{"message":"not found"}` for non-existing workflows

You can attach to a service/object invocation only if the invocation used an idempotency key:

```shell theme={null}
# Via invocation ID
curl localhost:8080/restate/invocation/myInvocationId/attach
curl localhost:8080/restate/invocation/myInvocationId/output

# For Services, via idempotency key
curl localhost:8080/restate/invocation/MyService/myHandler/myIdempotencyKey/attach
curl localhost:8080/restate/invocation/MyService/myHandler/myIdempotencyKey/output

# For Virtual Objects, via idempotency key
curl localhost:8080/restate/invocation/myObject/myKey/myHandler/myIdempotencyKey/attach
curl localhost:8080/restate/invocation/myObject/myKey/myHandler/myIdempotencyKey/output

# For Workflows, with the Workflow ID
curl localhost:8080/restate/workflow/MyWorkflow/myWorkflowId/attach
curl localhost:8080/restate/workflow/MyWorkflow/myWorkflowId/output
```

## OpenAPI support

Restate exposes for every service an OpenAPI 3.1 definition, to get it:

```shell theme={null}
curl localhost:9070/services/MyService/openapi > MyService_openapi.json
```

You can use this definition with any OpenAPI 3.1 compliant tool to generate clients for your service, such as [openapi-generator](https://openapi-generator.tech/).

Depending on the SDKs, the rich input/output JSON schemas are included as well. At the moment, rich schemas are supported for:

* [TypeScript SDK with Zod schemas](/develop/ts/serialization#zod-schemas)
* [Python SDK with Pydantic](/develop/python/serialization#pydantic) models
* Java and Kotlin SDK
