Action Context Schema

Learn more about configuring Action inputs, including using Liquid and catalog values.null

An Action’s rule and response fields support liquid templating. When templates are evaluated, they receive a context object. This allows the action to behave dynamically based on the information in the context.

Context fields are accessed using Liquid's double handle bar notation: {{ identifier }}. When evaluated this would be replaced by the matching value in the context.

The action context contains the following properties:

Service

When an action is defined to apply to a service, the actions will have access to the context of the specific service it is triggered against. These properties all refer to that service. For more information on how to configure an action to have access to service context, see the guide to creating your first action.

Description
service.frameworkThe primary software development framework that the service uses.
service.hrefA link to the HTML page for the service.
service.idThe unique identifier for the service.
service.languageThe primary programming language that the service is written in.
service.lifecycle_indexThe lifecycle stage of the service.
service.nameThe display name of the service.
service.productA product is an application that your end user interacts with. Multiple services can work together to power a single product.
service.service_repositoriesA list of repositories that are linked to the service. For details on what values are available on the repository, see Service Repositories.
service.slugThe URL friendly name of the service.
service.tier_indexThe software tier that the service belongs to.
service.ownerAn object representing the team that owns the service. For details on what values are available on the owner, see Owner.

Service Repositories

If a Service has a connected repositories, their details will also be available to the action.

Description
service_repositories[0].is_primaryIf true, the repository is considered the main source code for the service.**
service_repositories[0].display_nameThe name of the repository as it is displayed in OpsLevel.
service_repositories[0].deep_urlAn HTTP URL to the repository in the external Git Forge.
service_repositories[0].default_branchThe name of the default branch for the repository.

** primary is only true if the connected repo has an opslevel.yml file. If you do not use opslevel.yml to define your services and you use service_repositories[0].is_primary in a custom action, you will see a Liquid error when you try to run it:

❗️

Liquid Undefined Variable Error
Liquid error: undefined variable repository

User

Actions are invoked by an individual user. These properties all refer to that user.

Description
user.api_token_countThe number of api tokens owned by this user.
user.deactivatedTrue if this user is deactivated and cannot be used.
user.deactivated_atThe time that the user was deactivated.
user.emailThe user's email.
user.gravatar_urlThe url to the user's gravatar image.
user.has_providerWhether this user is managed externally.
user.hrefA link to the HTML page for the user.
user.idThe unique identifier for the user.
user.nameThe user's full name.
user.pendingWhether the user accepted their invitation to OpsLevel or not.
user.provisioned_byHow the user was provisioned. Possible values:, SCIM, OpsLevel CLI, Terraform, API, SSO (Okta), SSO, OpsLevel Admin, and Unknown.
user.roleThe user's assigned role.

Manual Inputs

Manual inputs are the fields presented to a user when they invoke an Action. They are also injected into the context and can be referenced using the value defined in the identifier property.

Manual inputs are available as sub-properties of the manualInputs property.

Given this defined input:

---
version: 1
inputs:   
  - identifier: bucketName
# ...

The value of this input would be available to the Action’s context with {{ manualInputs.bucketName }}.

Context from bindingValues in Manual Inputs

If:

  • your Action has configured manual inputs to generate a form at execution time
  • and those manual inputs include a dropdown with a binding to an OpsLevel resource
  • and the type of that resource is a object with multiple properties

Then you have access to properties on that resource type available to use under manualInputsfor the identifier set for that input.

For example, if:

  • if your Action has a manual input that includes a dropdown-type input with the identifier myTeam
  • and the binding property is set on that input
  • and the resource for that binding is team

Then you can get values on the selected team resource through its properties, using dot notation, in parts of the Action that use manualInputsin context. eg: manualInputs.myTeam.name

The properties available depend on the resource property on the binding object:

environments

The type of environments is [String!]!. These are not objects - there are no additional properties available for use here.

teams

DescriptionType
idThe unique identifier for the team.ID
nameThe team's display name.String
aliasA human-friendly, unique identifier for the team.String
aliasesA list of human-friendly, unique identifiers for the team.[String!]!
contactsThe contacts for the team.[{ type: String!, address: String! }]
hasChecksA flag to indicate if this team owns any checks.Boolean!

systems

DescriptionType
idThe unique identifier for the system.ID
nameThe system's display name.String

domains

DescriptionType
idThe unique identifier for the domain.ID
nameThe domain's display name.String

infrastructure

DescriptionType
idThe unique identifier for the infrastructure object.ID
nameThe infrastructure object's name.String
typeThe infrastructure object's type in OpsLevel (e.g. "Compute", "Database", etc.)String
provider_resource_typeThe infrastructure object's type according to the upstream provider (e.g. "EC2", "RDS", etc).String
integrationThe integration that was used to import the infrastructure object. Has subfields id, name, and type.Object

For more information, see our guide on configuring manual inputs.

Secrets

Secrets are a way to store information like API or Access tokens used in Action and Service Template webhooks. Secrets are only available in the Webhook URL, Payload and Headers fields and.

You can access Secrets values by using their alias as the sub-property of the secret or secrets property in the context.

For example, given a secret with the alias: opslevel_api_token.

The value of the secret would be available to the action's context with this syntax: {{ 'opslevel_api_token' | secret }}.

For more information, see our guide on secrets.

📘

Secrets will not appear in the Action Execution History's context object and will appear as ********when referenced in parts of the webhook

Owner

An owner reference is the Team responsible for a component in OpsLevel. An action's context may contain many owner references including action_owner -- the team responsible for the action being invoked and service.owner --. This field may be blank if the Team specified as the owner has been deleted from OpsLevel.

Description
action_owner.contactsA list of details for contacting the action owner. See Contact for more details.
action_owner.hrefA link to the HTML page for the action owner.
action_owner.idThe unique identifier for the action owner.
action_owner.managerThe user who manages the action owner. See User for more details.
action_owner.nameThe display name of the action owner.
action_owner.slugA human-friendly, unique identifier.

Contact

Contacts are the communication channels used to get in touch with the action owner.

Description
contact.addressThe contact address. Examples: Email(support@company.com) and Web(https://opslevel.com).
contact.contact_methodThe method of contact. Possible values:email, slack, slack_handle, and web.
contact.display_nameThe name shown in the UI for the contact.
contact.display_typeThe type shown in the UI for the contact. Possible values: Primary, Secondary, and None.
contact.idThe unique identifier for the contact.
contact.target_hrefThe fully qualified URI for the contact.

Response

The Response Details property injects an additional object into the Action’s context. These properties all refer to the response received from the webhook URL when invoking the action.

The response headers and body will be coerced into JSON if possible and can be referenced in the Liquid template as {{ response.headers.<property> }}.

Description
response.statusThe HTTP status code.
response.headersThe HTTP headers.
response.bodyThe response body.

Example Context

Action Template Context

{
    "user":
    {
        "id": "SOME-ID",
        "name": "First Last",
        "email": "flast@example.com",
        "href": "/users/SOME-ID",
        "role": "admin",
        "deactivated_at": null,
        "deactivated": false,
        "gravatar_src": "",
        "pending": false,
        "has_provider": false,
        "api_token_count": 3,
        "provisioned_by": "OpsLevel Admin"
    },
    "service":
    {
        "id": "SOME-ID",
        "name": "Django Test",
        "href": "/services/django_test",
        "product": null,
        "language": "Java",
        "framework": "Spring",
        "slug": "django_test",
        "tier_index": null,
        "lifecycle_index": null,
        "service_stat":
        {
            "num_checks": 9,
            "num_passing_checks": 4
        },
        "tags":
        [
            {
                "key": "is_approved",
                "value": "false",
                "id": "SOME-ID",
                "gid": "SOME-ID",
                "locked": false
            }
        ],
        "service_repositories":
        [
            {
                "id": 9999,
                "gid": "SOME-ID",
                "repo_path": "",
                "is_primary": false,
                "managed": false,
                "locked": false,
                "at_root": true,
                "display_name": "GROUP/django-test",
                "deep_url": "https://github.com/GROUP/django-test",
                "repository":
                {
                    "id": 9999,
                    "gid": "SOME-ID",
                    "name": "django-test",
                    "url": "https://github.com/GROUP/django-test",
                    "default_branch": "main",
                    "invalidated_at": null,
                    "active": true,
                    "forked": false,
                    "repo_key": "SOME-ID",
                    "display_name": "GROUP/django-test",
                    "description": null,
                    "type_string": "github",
                    "visible": true,
                    "archived_at": null,
                    "branch_protection": false,
                    "created_on": "2022-08-04T12:12:33.000000Z",
                    "account_name": "GROUP",
                    "type_display_name": "GitHub",
                    "icon": "github",
                    "integration_href": "https://app.opslevel.com/integrations/github/SOME-ID",
                    "locked": false,
                    "private": true,
                    "href": "/repositories/SOME-ID"
                }
            }
        ],
        "owner":
        {
            "id": "SOME-ID",
            "name": "Aes Sedai",
            "href": "/teams/aes_sedai",
            "slug": "aes_sedai",
            "service_stat":
            {
                "num_checks": 38,
                "num_passing_checks": 13
            },
            "manager":
            {
                "id": 9999999,
                "email": "sb-wot-md@example.com",
                "session_token": "SOME-ID",
                "last_sign_in_method": null,
                "name": "Moirane Damodred",
                "account_id": 999999,
                "accepted_tos_at": null,
                "role": "user",
                "provisioned_by_id": null,
                "provisioned_by_type": null,
                "provisioned_by_details": null,
                "deactivated_at": null,
                "created_at": "2022-06-29T22:43:06.619978Z",
                "updated_at": "2022-06-29T22:43:06.713373Z",
                "seen_team_cta": null
            },
            "tags":
            [],
            "contacts":
            [
                {
                    "id": 99999,
                    "address": "#the-white-tower",
                    "contact_method": "SLACK",
                    "display_name": "Slack Channel",
                    "display_type": null,
                    "target_href": "https://my-workspace.slack.com/channels/the-white-tower/",
                    "type": "Slack",
                    "short_name": "#the-white-tower",
                    "icon": "slack"
                }
            ]
        }
    },
    "action_owner":
    {
        "id": "SOME-ID",
        "name": "Team A",
        "href": "/teams/team_a",
        "slug": "team_a",
        "service_stat":
        {
            "num_checks": 0,
            "num_passing_checks": 0
        },
        "manager": null,
        "contacts":
        []
    },
    "manualInputs":
    {
        "message": "This is a message!"
    }
}

Filters

In addition to Liquid’s standard filters, we also support:

contacts_by_display_name

Find contacts by their display name

  • Input: {{ team | contacts_by_display_name: 'pagerduty' }}
  • Output: \[contact_1, contact_2\]

tag_value

Returns the value of the first matching tag.

  • Input: {{ service | tag_value: "version" }}
  • Output: "3.2.1"

tag_values

Returns the array of matching tag values.

  • Input: {{ service | tag_values: "ip" }}
  • Output: \["1.1.1.1", "2.2.2.2"\]

This can be combined with the standard filters to extract specific values:

  • Input: {{ service | tag_values: "ip" | last }}
  • Output: "1.1.1.1"