Skip to content

Receptionist Service

A receptionist service is what is used to start a workflow.


This module has a configuration file (receptionist.yaml by default) that describes the host, port, ssl_context, trusted_authorities, and logfile to use. It can also enable insecure logins.

If no configuration file is found it will default to the following values:

kind: ServiceConfig
current-context: default
- context:
    port: 7774
    ssl_context: adhoc
      token: invalid
  name: default

ssl_context is either adhoc, a list of two items (certificate file path and private key file path), or disabled (not recommended, will switch to plain HTTP).

A context can also contain a trusted_authorities, which is a list of public key files, used for token validation.

A context can also allow for insecure (token-less) logins, if enable_insecure_login is set to true (by default, insecure logins are disabled).

Insecure logins, if enabled, are only allowed from a given address ( by default). This can be overridden by specifying insecure_bind_address.


The following command starts the receptionist service:

python3 -m opentf.core.receptionist [--context context] [--config configfile]


This module exposes one endpoint:

  • /workflows (POST or multipart/form-data)

Whenever calling this endpoint, a signed token must be specified via the Authorization header.

This header will be of form:

Authorization: Bearer xxxxxxxx

It must be signed with one of the trusted authorities specified in the current context.

On success, a workflow ID is returned (in details.workflow_id).

There are two ways a workflow can be provided.

The first way is by using a POST request, the POST body being the workflow definition.

The second way is by using a multipart/form-data request. In this case, you must provide a workflow field or file. You may also provide a variables field or file.

The examples below use the curl command. If you intend to start a lot of workflows from the command line, it is recommended to use a tool such as opentf-ctl. Please refer to “Tools - Run workflows” for more information.


variables, if specified, are merged in the workflow variables. Variables already defined in the workflow are overwritten by the ones provided by a field or file.

You must use a multipart/form-data request if you want to add environment specific variables to your workflow.

If provided by a field, variables must be separated by linefeed. If provided by a file, there must be one variable per line.


If you are on Windows and cannot use PowerShell, use a file, as described below. It is not practical to pass linefeeds using CMD.

By field:

curl ... -F variables=$'FOO=abc def\nBAR=123' ...
curl.exe ... -F variables="FOO=abc def`nBAR=123" ...

By file:

curl ... -F variables=@MyVariables ...

The MyVariables file being for example:

FOO=abc def

If a variable is defined more than once, its last definition is used.

Resource files

If your workflow contains a .resources.files part, you must also provide one file per defined entry in .resources.files. You cannot use the field format for files.

You must use a multipart/form-data request if your workflow contains a .resources.files part.


Assuming an existing workflow.yaml YAML workflow in the current directory, you can call the endpoint using a POST request as such:

curl -X POST \
     -H "Authorization: Bearer ${TOKEN}" \
     -H "Content-type: application/x-yaml" \
     --data-binary @workflow.yaml \
curl -X POST ^
     -H "Authorization: Bearer %TOKEN%" ^
     -H "Content-type: application/x-yaml" ^
     --data-binary @workflow.yaml ^
curl.exe -X POST `
     -H "Authorization: Bearer $Env:TOKEN" `
     -H "Content-type: application/x-yaml" `
     --data-binary @workflow.yaml `

If workflow.yaml is a JSON workflow, you can alternatively use the following command:

curl -X POST \
     -H "Authorization: Bearer ${TOKEN}" \
     -H "Content-Type: application/json" \
     --data-binary @workflow.yaml \
curl -X POST ^
     -H "Authorization: Bearer %TOKEN%" ^
     -H "Content-Type: application/json" ^
     --data-binary @workflow.yaml ^
curl.exe -X POST `
     -H "Authorization: Bearer $Env:TOKEN" `
     -H "Content-Type: application/json" `
     --data-binary @workflow.yaml `

(Strictly speaking, as YAML is a superset of JSON, the first syntax will work just as well.)

You can call the endpoint using a multipart/form-data request too:

curl -X POST \
     -H "Authorization: Bearer ${TOKEN}" \
     -F workflow=@workflow.yaml \
curl -X POST ^
     -H "Authorization: Bearer %TOKEN%" ^
     -F workflow=@workflow.yaml ^
curl.exe -X POST `
     -H "Authorization: Bearer $Env:TOKEN" `
     -F workflow=@workflow.yaml `

Assuming your workflow declares two .resources.files entries, as such:

  name: Plenty
  SERVER: foo
  SQUASH_USER: foobar
  - report1
  - report2

You can call the endpoint using the following multipart/form-data request:

curl -X POST \
     -H "Authorization: Bearer ${TOKEN}" \
     -F workflow=@workflow.yaml \
     -F report1=@report1.html \
     -F report2=@report2.xml \
curl.exe -X POST \
     -H "Authorization: Bearer $Env:TOKEN" `
     -F workflow=@workflow.yaml `
     -F report1=@report1.html `
     -F report2=@report2.xml `

Here, we also provide two variables, SQUASH_USER and SQUASH_PASSWORD.

The SQUASH_USER variable is specified in the workflow, but its value will be overwritten with the value set in the curl call.

The SQUASH_PASSWORD variable will be available for use in the workflow, with the value set in the curl call.

The SERVER variable specified in the workflow remains available and unchanged.