Tutorial
Building custom skills with OpenAPI using watsonx Orchestrate
Import, enhance, publish, and run custom skill in watsonx OrchestrateIBM watsonx Orchestrate is a platform that helps enterprises to automate tasks, simplify complex processes, and ultimately save teams time and effort.
At the heart of watsonx Orchestrate lies its core: skills. A skill is a capability that is used to complete a task. Skills comprise interconnected actions. In other words, a skill can consist of either a single action or a series of actions that collectively achieve a task. The complexity of a skill varies significantly; it can range from a straightforward, single action to a sophisticated sequence of actions necessary to fulfill a particular task. For example, appending a row to an Excel spreadsheet constitutes a singular action, a discrete task achieved through a single action. Or, for HR personnel, you could create a complex set of skills that you link together that finds candidates to interview on LinkedIn, collects a list of all candidates, emails them about a job opportunity, sends out calendar invites for interviews.
There are two types of skills: pre-built skills and custom skills. Pre-built skills are created by IBM (or Business Partners) to accelerate common workflows in key business functions. Custom skills are imported skills that you, as a builder, build and import into watsonx Orchestrate, or discover from applications. With custom skills, you can combine internal systems, third-party tools, and pre-built skills to accomplish use cases for your organization's specific needs.
You can build custom skills from apps, such as IBM Cloud Pak for Business Automation, IBM Robotic Process Automation, or IBM Operational Decision Manager, or from an OpenAPI file.
The OpenAPI Specification (OAS) defines a standard, programming-language-agnostic interface description for HTTP APIs. An OpenAPI allows both humans and computers to discover and understand the capabilities of a service without requiring access to source code, additional documentation, or inspection of network traffic. A developer can understand and interact with the remote service implemented as an OpenAPI with a minimal amount of implementation logic. Similar to what interface descriptions have done for lower-level programming, the OpenAPI Specification removes the guesswork in calling a service.
To build a custom skill from an OpenAPI file, you need to be sure to review the OpenAPI specification and fully understand OpenAPI data types and OpenAPI objects.
Prerequisites
To build a custom skill with OpenAPI requires:
- An OpenAPI file (in JSON/YAML format)
- A text editor such as Visual Studio Code or Notepad ++
- A watsonx Orchestrate environment access with the Builder role
Steps
Let’s call a sample API that returns a list of employees in a table. The names, job roles, and emails that this API returns are for demonstration purposes only.
Step 1. Create an OpenAPI file
- Open a text editor and create a new file.
Map the custom skill file with the OpenAPI Specification (OAS).
Use the openapi property to set the version of your OAS. Add openapi property into this file.
{ "openapi": "3.0.1" }Map the OAS info object.
Use the info section to set the API metadata. The title and version properties are mandatory in this section, but you can also add the IBM x-properties to provide more information about your API.
{ "openapi": "3.0.1", "info": { "title": "Sample employee", "description": "List the name, email, and job title of sample employee", "version": "1.0.0", "x-ibm-application-icon": "<svg width=\"44\" height=\"44\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xml:space=\"preserve\" overflow=\"hidden\"><defs><clipPath id=\"clip0\"><rect x=\"592\" y=\"312\" width=\"44\" height=\"44\"/></clipPath><clipPath id=\"clip1\"><rect x=\"592\" y=\"312\" width=\"43\" height=\"43\"/></clipPath><clipPath id=\"clip2\"><rect x=\"592\" y=\"312\" width=\"43\" height=\"43\"/></clipPath><clipPath id=\"clip3\"><rect x=\"592\" y=\"312\" width=\"43\" height=\"43\"/></clipPath></defs><g clip-path=\"url(#clip0)\" transform=\"translate(-592 -312)\"><g clip-path=\"url(#clip1)\"><g clip-path=\"url(#clip2)\"><g clip-path=\"url(#clip3)\"><path d=\"M615.74 315.135C615.74 315.878 615.138 316.479 614.396 316.479 613.654 316.479 613.052 315.878 613.052 315.135 613.052 314.393 613.654 313.792 614.396 313.792 615.138 313.792 615.74 314.393 615.74 315.135Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\"/><path d=\"M617.979 319.167C617.979 319.909 617.378 320.51 616.635 320.51 615.893 320.51 615.292 319.909 615.292 319.167 615.292 318.425 615.893 317.823 616.635 317.823 617.378 317.823 617.979 318.425 617.979 319.167Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\"/><path d=\"M613.052 318.271C613.052 319.013 612.45 319.615 611.708 319.615 610.966 319.615 610.365 319.013 610.365 318.271 610.365 317.529 610.966 316.927 611.708 316.927 612.45 316.927 613.052 317.529 613.052 318.271Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\"/><path d=\"M614.396 323.198C614.396 324.187 613.594 324.99 612.604 324.99 611.615 324.99 610.812 324.187 610.812 323.198 610.812 322.208 611.615 321.406 612.604 321.406 613.594 321.406 614.396 322.208 614.396 323.198Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\"/><path d=\"M622.234 349.446 617.083 337.8 617.083 329.917C617.083 328.304 618.382 327.632 618.427 327.587 618.875 327.364 619.054 326.826 618.83 326.378 618.651 326.065 618.338 325.885 617.979 325.885L609.021 325.885C608.662 325.885 608.349 326.065 608.17 326.378 607.946 326.826 608.125 327.364 608.573 327.587 608.573 327.587 609.917 328.304 609.917 329.917L609.917 337.8 604.766 349.446C604.407 350.297 604.497 351.237 604.99 351.999 605.482 352.76 606.333 353.208 607.229 353.208L619.771 353.208C620.667 353.208 621.518 352.76 622.01 351.999 622.503 351.237 622.593 350.297 622.234 349.446ZM615.292 329.917 615.292 331.708 611.708 331.708 611.708 329.917C611.708 328.976 611.44 328.259 611.126 327.677L615.919 327.677C615.56 328.259 615.292 328.976 615.292 329.917Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\"/></g></g></g></g></svg>", } }Map the OAS servers object.
Use the servers section to set the array of servers that provides connectivity information to a target server.
"servers": [ { "url": "https://b25yxaezee.execute-api.us-east-2.amazonaws.com ", } ]Map the OAS paths object.
Use the paths section to set the relative paths to the individual endpoints and their operations.
"paths": { "/demo/HelloTable": { "get": { "summary": "Retrieve employees", "description": "Retrieve a table with name, role, and email of the sample employees", "responses": { "200": { "description": "Successfully retrieved the data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/hello-table" } } } } } } } }Map the OAS components object.
Use the components section to set reusable properties for different aspects of the OpenAPI. You must set the securitySchemes in this section size as it is responsible to connect the app to Orchestrate.
"components": { "schemas": { "hello-table": { "type": "object", "properties": { "body": { "$ref": "#/components/schemas/table-body" } } }, "table-body": { "type": "object", "properties": { "hwtable": { "type": "array", "title": "Team members", "items": { "type": "object", "properties": { "fname": { "type": "string", "title": "First Name" }, "lname": { "type": "string", "title": "Last Name" }, "role": { "type": "string", "title": "Job Role" }, "email": { "type": "string", "title": "Email" } } } } } } }, "securitySchemes": { "bearerAuth": { "type": "apiKey", "in": "header", "name": "Authorization" } } }
Instead of creating this OAS file yourself, you can download the zip file on to your local system, unzip it, and navigate to the sample-employee folder. Within this folder, you can select either the sample-employees.json or sample-employees.yaml file and confirm that all the OpenAPI specification aligns with the steps outlined above.
Step 2. Import the custom skill from OpenAPI file
- From the main menu, select Skills.
- Click Add skills.
- Click From files.
Click the option “Drag and drop files here or click to upload”.

Select your personalized skill file from the OpenAPI file location. watsonx Orchestrate validates the schema and notifies you if your skill package is valid. Then, click Next.

From the list of skills, select Retrieve employees and click Add.
Step 3. Enhance and publish the custom skill
- From the main menu, select Skills.
- On the Skills and apps page, click the vertical ellipsis button next to the
Retrieve employeeskill, and then select Enhance this skill. - From the Enhance page, click the Phrases tab.
Enter the following phrases in the Enter new train phrase field. Press enter after you insert each phrase:
- Retrieve employees.
- I want to retrieve employees.
Can you retrieve the employees list ?

Click Publish to publish the skill.
Step 4. Connect to the Sample employee app
Now that you published the custom skill to watsonx Orchestrate, you can add it to your personal skill set and use it. First, you need to connect to the Sample employee app.
- On the Orchestrate home page, click Add skills from the catalog.
- Click the Sample employee app tile.
- Click Connect app.
- Enter any data in API Key, for example, 123.
- Click Connect app.

Step 5. Run the custom skill
Now, you can test the custom skill.
- On the Orchestrate home page, click the chat.
- Type “Can you retrieve the employees list ?” and press Enter.
- Click Apply.

Summary
In this tutorial you learned how to configure an OpenAPI file and prepare it for us as a watsonx Orchestrate skill. Then, you learned how to import, enhance, publish, and run the skill in watsonx Orchestrate.
Learn more about building skills, creating OpenAPI files, and guidelines for designing skills in the watsonx Orchestrate docs.