Service specification
If you haven't done it yet, read about services' main concepts.
Also keep these handy references:
- Service Specification API
- Schemas
Design your service specification
Before you create the service, ask yourself a few questions. We’ll present them in a table so you can see how your answers impact your service specification:
| Question | Guidance |
|---|---|
| What's the name for the service? | Choose a natural name (e.g., MySQL) and set it into the name field. |
| Which properties do I need to hold for the service? | These are the properties that define the service. They are usually a combination of input parameters plus values obtained from the cloud provider upon service creation. Set these as a JSON schema in the attributes field. |
| Where in the organization is the service going to be available? | A good default is to start by making the service visible everywhere with the value organization=your-org-id:account=*. Set your choice in the visible_to array. |
| What can be done with the service? | Define standard actions in the service specification to control what users can do with the service. |
Defining standard actions in the service spec
New service specifications automatically generate their standard actions: create, update, and delete (use_default_actions defaults to true). The three actions are built from the spec's attributes schema and stay in sync with it as it evolves, with no manual upkeep.
To shape how the generated actions behave:
- Use the
visibleOnandeditableOnkeywords in your schema to control when each property should be shown or editable during the instance lifecycle.
For example:
visibleOn: ["create", "update"]makes a property visible when creating or updating an instance.editableOn: ["create"]makes a property editable only at creation time.
You can check our Special schema keys page for more information on these keywords.
By using this approach, you manage everything from a single source of truth, the service specification schema, without the need to define or maintain separate action specifications.
We recommend keeping the autogenerated standard actions unless:
- You need to update your standard actions. Autogenerated actions can't be edited directly, so changes and updates must be made using action specifications.
- You prefer to manage the default create, update, and delete actions manually using action specifications.
In both cases, set "use_default_actions": false explicitly when creating the specification. On specs with autogenerated actions you can still add custom actions, but you can't override the generated create, update, or delete. Specifications created before this default changed keep the value they were saved with.
See Action specifications for more information on how to design actions for your services.
Automatic instance naming
New service specifications also default to "use_default_naming": true, which makes the name field optional when someone creates a service from your spec:
- If the caller provides a name, it's used as-is.
- If not, nullplatform generates one from the specification name plus a short suffix (like
redis a4f3). - If your attributes schema defines its own
nameproperty, its value becomes the instance name, and the two are kept in sync.
Set "use_default_naming": false if you want callers to always provide a name explicitly. Specifications created before this flag existed keep requiring a name.
Create a service specification
You can create a service specification using our CLI or API.
You can also review and edit service and link specifications directly from the UI, making it easier than ever to work with your services.
Go to Platform settings > Services and click New service specification.
Here’s an example of a service specification that includes standard actions:
- CLI
- cURL
np service specification create \
--body '{
"name": "my-service-specification",
"type": "dependency",
"visible_to": [
"organization=1:account=1",
"organization=1:account=2"
],
"use_default_actions": true, // Default for new specs. Set to 'false' to define create/update/delete yourself
"attributes": { // Defines the structure and layout of the form
"schema": {
"type": "object",
"properties": {
"my_string_property": {
"type": "string",
"visibleOn": ["read", "create", "update"],
"editableOn": ["create"]
},
"my_number_property": {
"type": "number",
"default": 0,
"visibleOn": ["read", "create"],
"editableOn": ["create"]
}
},
"required": [
"my_string_property"
]
},
"values": {}
}
}'
curl -L 'https://api.nullplatform.com/service_specification' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer the-token' \
-d '{
"name": "my-service-specification",
"type": "dependency",
"visible_to": [
"organization=1:account=2:namespace=3",
"organization=1:account=2:namespace=4"
],
"use_default_actions": true, // Default for new specs. Set to 'false' to define create/update/delete yourself
"attributes": { // Defines the structure and layout of the form
"schema": {
"type": "object",
"properties": {
"my_string_property": {
"type": "string",
"visibleOn": ["read", "create", "update"],
"editableOn": ["create"]
},
"my_number_property": {
"type": "number",
"default": 0,
"visibleOn": ["create", "update"],
"editableOn": ["create"]
}
},
"required": [
"my_string_property"
]
},
"values": {}
}
}'
The JSON schema under attributes determines the service's attributes, fields, and layout in the UI. These properties appear in the See details, Create, or Edit views in the nullplatform interface.
You can further enhance the rendering of that section using UI Schema.
Some attributes to consider
Let’s take a closer look at a few of the key fields in the JSON:
visible_to: Defines visibility for the service using NRN. Each entry in this array follows the formatorganization=<org_id>:account=<account_id>:namespace=<namespace_id>. For example:"organization=1:account=2:namespace=3"makes the service visible to namespace3under account2of organization1."organization=1:account=2:namespace=*"makes the service visible to all namespaces under account2.
use_default_actions: Autogenerates the standardcreate,update, anddeleteactions from the attributes schema and keeps them in sync with it. Defaults totrueon new specifications; set it tofalseto define those actions yourself.use_default_naming: Makes the instancenameoptional: when no name is sent, nullplatform generates one or takes it from the schema'snameproperty. Defaults totrueon new specifications.attributes: Describes the configuration and layout of the service using JSON Schema.
You can always refer to our API reference for more details on service specification requests.
Restrict services to specific scopes
Not every service makes sense in every scope. For example, a Helm Release Deployer should only be available in Kubernetes-based scopes, while an Airflow operator should only work in Airflow scopes.
To prevent mismatches, you can restrict services and links to specific scope types or scope specifications. This ensures they are only visible and usable in the right environments.
How it works
You can restrict scope compatibility by defining the scopes attribute in your
service specification or link specification.
The scopes field supports scope types (like AWS:SERVERLESS:LAMBDA or AZURE:WEB_POOL:AKS), and scope spec ID.
{
"scopes": {
"values": [
"AWS:SERVERLESS:LAMBDA",
"AWS:WEB_POOL:EC2INSTANCES",
"uuid-of-a-specific-scope-specification"
]
}
}
Examples:
- An Airflow operator service restricted to your
AIRFLOW:JOBspec (UUID). - A Helm Release Deployer restricted to
K8S:DEPLOYMENT(UUID). - An SQS Publisher restricted to
AWS:SERVERLESS:LAMBDAto ensure it only appears where event-driven compute is supported.
📖 See our API reference for more info on supported scope types and usage.