# Quick Start

This page walks you through the smallest complete nativeMsg experience, explains every field, and shows how to validate an experience file against the schema before deploying it.

## Prerequisites

* A text editor or IDE with JSON support
* Node.js ≥ 16, Python ≥ 3.8, or a shell with `curl` available (for validation)
* A nativeMsg account and API credentials (for deployment)

## Minimal Working Example

The following experience defines a single workflow that responds to a "greeting" intent with a text message and two quick replies.

```json
{
  "name": "Support Bot v1",
  "welcomeMessageExecute": "greeting",
  "workflows": [
    {
      "name": "greeting",
      "intents": ["greeting"],
      "expressions": [
        "hello",
        "hi",
        "hey there",
        "good morning"
      ],
      "actions": [
        {
          "name": "send-greeting",
          "send": {
            "message": {
              "text": "Welcome to Acme Support. What can I help you with today?",
              "quickReplies": [
                {
                  "type": "text",
                  "title": "Track an order",
                  "payload": "track_order"
                },
                {
                  "type": "text",
                  "title": "Return an item",
                  "payload": "return_item"
                }
              ]
            }
          }
        }
      ]
    }
  ]
}
```

### Field-by-Field Annotation

| Field                     | Path                                     | Type   | Required    | Description                                                                                                                                                      |
| ------------------------- | ---------------------------------------- | ------ | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`                    | `$.name`                                 | string | **Yes**     | Human-readable name for this experience. 1–100 characters.                                                                                                       |
| `welcomeMessageExecute`   | `$.welcomeMessageExecute`                | string | No          | Name of the workflow to run when the channel invitation is displayed. Must match a workflow `name`.                                                              |
| `workflows`               | `$.workflows`                            | array  | **Yes**     | Ordered list of [Workflow](https://playbook.nativemsg.com/rcs-experience-schema/rcs-experience-schema/broken-reference) objects. Must contain at least one item. |
| `workflows[].name`        | `$.workflows[0].name`                    | string | No          | Unique identifier for this workflow. Must not start with `nm:`. Used by `execute`, `goto`, and `welcomeMessageExecute`.                                          |
| `workflows[].intents`     | `$.workflows[0].intents`                 | array  | **Yes**     | Intent names or [IntentObject](https://playbook.nativemsg.com/rcs-experience-schema/rcs-experience-schema/broken-reference) entries that trigger this workflow.  |
| `workflows[].expressions` | `$.workflows[0].expressions`             | array  | No          | Natural language training phrases. Strings or [Expression](https://playbook.nativemsg.com/rcs-experience-schema/rcs-experience-schema/broken-reference) objects. |
| `workflows[].actions`     | `$.workflows[0].actions`                 | array  | **Yes**     | Sequence of [Action](https://playbook.nativemsg.com/rcs-experience-schema/rcs-experience-schema/broken-reference) objects to execute.                            |
| `actions[].name`          | `$.workflows[0].actions[0].name`         | string | No          | Unique identifier for this action within its workflow. Must not start with `nm:`.                                                                                |
| `actions[].send.message`  | `$.workflows[0].actions[0].send.message` | object | No          | [Message](https://playbook.nativemsg.com/rcs-experience-schema/rcs-experience-schema/broken-reference) to deliver to the user.                                   |
| `message.text`            | `...message.text`                        | string | Conditional | Message body. Maximum 3072 characters. Required unless another content field is present.                                                                         |
| `message.quickReplies`    | `...message.quickReplies`                | array  | No          | Up to 11 [QuickReply](https://playbook.nativemsg.com/rcs-experience-schema/rcs-experience-schema/broken-reference) objects.                                      |
| `quickReplies[].type`     | `...quickReplies[0].type`                | string | **Yes**     | Reply type. `"text"` renders as a tappable chip.                                                                                                                 |
| `quickReplies[].title`    | `...quickReplies[0].title`               | string | Conditional | Display label. Required when type is `text` or `postback`. Maximum 25 characters.                                                                                |
| `quickReplies[].payload`  | `...quickReplies[0].payload`             | string | No          | Value sent back to the platform when selected. Maximum 1000 characters.                                                                                          |

{% hint style="info" %}
The `expressions` array teaches the NLU engine which phrases should match the `greeting` intent. You do not need expressions for intents that are matched by exact name or keyword.
{% endhint %}

{% hint style="danger" %}
Both `name` and `workflows` are required at the root level. An experience missing either property will fail schema validation and be rejected by the API.
{% endhint %}

## Schema Validation

Validate your experience file locally before deploying. The schema is published at:

```
https://docs.nativemsg.com/schemas/rcs-experience-schema-1-0-0.json
```

{% tabs %}
{% tab title="Node.js (ajv)" %}
{% code title="validate.js" %}

```javascript
const Ajv = require('ajv');
const addFormats = require('ajv-formats');
const fs = require('fs');
const https = require('https');

async function fetchSchema(url) {
  return new Promise((resolve, reject) => {
    https.get(url, (res) => {
      let data = '';
      res.on('data', (chunk) => { data += chunk; });
      res.on('end', () => resolve(JSON.parse(data)));
      res.on('error', reject);
    });
  });
}

async function validate(experienceFile) {
  const ajv = new Ajv({ allErrors: true });
  addFormats(ajv);

  const schema = await fetchSchema(
    'https://docs.nativemsg.com/schemas/rcs-experience-schema-1-0-0.json'
  );
  const validate = ajv.compile(schema);

  const experience = JSON.parse(fs.readFileSync(experienceFile, 'utf8'));
  const valid = validate(experience);

  if (valid) {
    console.log('✓ Experience is valid');
  } else {
    console.error('✗ Validation errors:');
    validate.errors.forEach((err) => {
      console.error(`  ${err.instancePath} ${err.message}`);
    });
    process.exit(1);
  }
}

validate(process.argv[2] || 'experience.json');
```

{% endcode %}

Install dependencies and run:

```bash
npm install ajv ajv-formats
node validate.js experience.json
```

{% endtab %}

{% tab title="Python (jsonschema)" %}
{% code title="validate.py" %}

```python
import json
import sys
import urllib.request
from jsonschema import validate, ValidationError, Draft7Validator

SCHEMA_URL = 'https://docs.nativemsg.com/schemas/rcs-experience-schema-1-0-0.json'

def load_schema(url):
    with urllib.request.urlopen(url) as response:
        return json.loads(response.read())

def validate_experience(experience_file):
    schema = load_schema(SCHEMA_URL)
    with open(experience_file, 'r') as f:
        experience = json.load(f)

    validator = Draft7Validator(schema)
    errors = list(validator.iter_errors(experience))

    if not errors:
        print('✓ Experience is valid')
    else:
        print('✗ Validation errors:')
        for error in errors:
            path = ' > '.join(str(p) for p in error.absolute_path) or '(root)'
            print(f'  [{path}] {error.message}')
        sys.exit(1)

if __name__ == '__main__':
    experience_file = sys.argv[1] if len(sys.argv) > 1 else 'experience.json'
    validate_experience(experience_file)
```

{% endcode %}

Install dependencies and run:

```bash
pip install jsonschema
python validate.py experience.json
```

{% endtab %}

{% tab title="CLI (ajv-cli)" %}

```bash
# Install ajv-cli globally
npm install -g ajv-cli ajv-formats

# Download the schema locally (optional, can also reference by URL)
curl -o nativemsg-schema.json \
  https://docs.nativemsg.com/schemas/rcs-experience-schema-1-0-0.json

# Validate your experience file
ajv validate \
  -s nativemsg-schema.json \
  -d experience.json \
  --spec=draft7 \
  -c ajv-formats
```

Expected output for a valid file:

```
experience.json valid
```

Expected output for an invalid file:

```
experience.json invalid
[
  {
    "instancePath": "",
    "schemaPath": "#/required",
    "keyword": "required",
    "params": { "missingProperty": "workflows" },
    "message": "must have required property 'workflows'"
  }
]
```

{% endtab %}
{% endtabs %}

## Next Steps

* Read [Concepts](https://playbook.nativemsg.com/rcs-experience-schema/rcs-experience-schema/broken-reference) for normative definitions of all schema terms
* See [Reference: Workflow](https://playbook.nativemsg.com/rcs-experience-schema/rcs-experience-schema/broken-reference) for the complete workflow specification
* See [Reference: Actions](https://playbook.nativemsg.com/rcs-experience-schema/rcs-experience-schema/broken-reference) for all available action types
* Browse [Common Patterns](https://playbook.nativemsg.com/rcs-experience-schema/rcs-experience-schema/broken-reference) for ready-to-use experience recipes
