> ## Documentation Index
> Fetch the complete documentation index at: https://developer.jobmojito.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Format content with Markdown

> The Markdown vocabulary JobMojito renders — headings, tables, code, plus chips, callouts, cards, columns and buttons.

Several JobMojito fields are rendered as Markdown rather than shown as plain text. This page is the complete list of what you can write in them and what the candidate sees.

## Fields that render Markdown

| Field                       | Endpoint                                                                          | Where the candidate sees it                          |
| --------------------------- | --------------------------------------------------------------------------------- | ---------------------------------------------------- |
| `content_md`                | `catalogue-tag-create`, `catalogue-tag-update`                                    | A coaching catalogue directory page                  |
| `description_long`          | `job-interview-create`, `job-interview-update`, `job-interview-create-from-array` | The position / session detail page                   |
| `position_description_long` | `job-interview-create-for-candidate-with-token`                                   | The position detail page of the interview it creates |

Read the current value back with `catalogue-tag-get` (`content_md`) or `job-interview-get` (`interview_description_long`).

<Info>
  Every field above uses the same vocabulary and the same renderer. Only `content_md` additionally accepts the catalogue directives at the end of this page, because only a directory page has sessions to place.
</Info>

<Warning>
  These fields are **replaced wholesale**, not merged. Read the current value, edit the whole thing, and send the whole thing back.
</Warning>

## Sending Markdown over the API

Markdown is line-based and JSON strings are not, so newlines have to be escaped as `\n` in the request body:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://cool.jobmojito.com/functions/v1/catalogue-tag-update \
    -H "Authorization: Bearer $SUPABASE_JWT" \
    -H "Content-Type: application/json" \
    -d '{
      "id": "sales-coaching-en",
      "content_md": "## Sales coaching\n\nStart with discovery.\n\n[chip:6 sessions] [chip:Beginner,tone=accent]\n\n[sessions:filter=discovery,limit=6]\n"
    }'
  ```

  ```python Python theme={null}
  import json, requests

  content_md = """## Sales coaching

  Start with discovery.

  [chip:6 sessions] [chip:Beginner,tone=accent]

  [sessions:filter=discovery,limit=6]
  """

  requests.post(
      "https://cool.jobmojito.com/functions/v1/catalogue-tag-update",
      headers={"Authorization": f"Bearer {token}"},
      json={"id": "sales-coaching-en", "content_md": content_md},
  )
  ```
</CodeGroup>

## Standard Markdown

### Headings

```markdown theme={null}
# Page title
## Section
### Subsection
```

Bold text inside a heading is highlighted in your portal's accent colour, so `## The **fast** track` gives you a coloured word rather than a bolder one.

A heading is given twice as much space above it as below it, so it reads as belonging to the section it opens. A heading at the very top of the content gets no space above it, and two headings in a row are treated as a title and its subtitle and kept close together.

### Text

```markdown theme={null}
**bold**, *italic*, ~~struck through~~, `inline code`

A blank line starts a new paragraph.
Two spaces at the end of a line  
force a line break inside one.
```

### Lists

```markdown theme={null}
- Bullet
- Another bullet
  - Nested bullet

1. First
2. Second

- [ ] Task not done
- [x] Task done
```

### Links and images

```markdown theme={null}
[Link text](https://example.com)
[Internal link](/catalogue)
![Alt text](https://example.com/picture.png)
```

Images are constrained to the width of the column and get rounded corners automatically.

### Quotes

```markdown theme={null}
> A quotation.
```

For a highlighted aside, use `[note]` instead — see below.

### Tables

```markdown theme={null}
| Session | Length | Level |
| --- | --- | --- |
| Screening | 12 min | Beginner |
| Deep dive | 40 min | Advanced |
```

Wide tables scroll sideways inside their own box rather than stretching the page.

### Code

Fence a block with three backticks and, optionally, a language name:

````markdown theme={null}
```sql
select count(*) from results;
```
````

The block renders on a dark background, with the language shown above it and a copy button.

Nothing inside a fence is interpreted, which is how you show an example of the syntax itself. Indented code blocks are **not** supported — always use fences.

### Horizontal rule

```markdown theme={null}
---
```

## Rich elements

These are written as `[name]` or `[name:argument]`. An argument is either a single value or a comma-separated list of `key=value` pairs.

### Chip — inline

A small pill for a label, a level, a duration or a status. Write it anywhere in a sentence.

```markdown theme={null}
[chip:Beginner] [chip:6 sessions] [chip:New,tone=accent] [chip:Sold out,tone=danger]
```

`tone` is one of `neutral` (the default), `accent`, `success`, `warning`, `danger`, `info`.

### Keyboard key — inline

```markdown theme={null}
Press [kbd:Ctrl] + [kbd:K] to search.
```

### Note — block

A tinted aside. Put it on its own lines and close it with `[/note]`. The body is ordinary Markdown.

```markdown theme={null}
[note:tip]
Book fifteen minutes a day. Short and regular beats one long session.
[/note]
```

With a heading:

```markdown theme={null}
[note:warning,title=Before you book]
Sessions cannot be rescheduled within 24 hours.
[/note]
```

`tone` is one of `note` (the default), `tip`, `info`, `warning`, `danger`. `caution` and `important` are accepted as spellings of `warning`, and `success` as a spelling of `tip`.

<Tip>
  The title is optional and is shown exactly as you type it — there is no default label, so a note carries no English wording unless you write it. Put the title in the same language as the rest of the content.
</Tip>

### Card — block

A bordered, raised box around any Markdown.

```markdown theme={null}
[card]
### Screening simulation
Twelve minutes, with feedback on structure and clarity.
[/card]
```

### Columns — block

Lays its children out side by side: one column on a phone, two from tablet width up, and the requested number on a wide screen.

```markdown theme={null}
[columns:3]
[card]
### Fast
Twelve minutes.
[/card]
[card]
### Thorough
Forty minutes.
[/card]
[card]
### Custom
Bring your own brief.
[/card]
[/columns]
```

`[columns:2]`, `[columns:3]` and `[columns:4]` are supported; anything else falls back to two.

Each block inside becomes one cell. To put several blocks in one cell, wrap them in `[column] … [/column]`:

```markdown theme={null}
[columns:2]
[column]
## What you get
- A recorded session
- A written report
[/column]
[column]
## What you need
Twenty quiet minutes and a working microphone.
[/column]
[/columns]
```

### Button — block

A call to action. Needs both a label and an `href`.

```markdown theme={null}
[button:Book a session,href=/catalogue,tone=accent]
[button:Read the guide,href=https://example.com]
```

`tone` is one of `primary` (the default, dark), `accent` (your brand colour) or `secondary` (outlined). External links open in a new tab. Two buttons written on consecutive lines sit next to each other.

### Divider — block

```markdown theme={null}
[divider]
```

A quieter rule than `---`, with more space around it.

## Catalogue directives

`content_md` only. Each must sit alone on its line, and each draws from the sessions and sub-directories the directory already contains — a directive can never surface a session the directory itself would not show.

```markdown theme={null}
[plan-progress]                        the learner's coaching-plan progress
[directory:sales-coaching-closing-en]  one sub-directory card
[session:screening-en]                 one session card, by id or code
[sessions]                             every session in this directory
[sessions:negotiation]                 sessions matching a term
[sessions:filter=negotiation,limit=6]  the same, capped
```

`filter` matches a session's tags first (whole tags, so `new` does not match `renewal`), then its name, description and code. Accents are ignored, so `filter=simulacion` finds "Simulación". Several terms can be given, separated by commas.

Card directives written on consecutive lines share one row:

```markdown theme={null}
[session:screening-en]
[session:negotiation-en]
[session:panel-en]
```

<Tip>
  If `[sessions:filter=…]` renders nothing, check `matched_sessions` from `catalogue-tag-get` first — the filter narrows that set, it does not widen it. See [Build a coaching catalogue](/cookbooks/build-a-coaching-catalogue) for how sessions get into a directory in the first place.
</Tip>

### A worked directory page

```markdown theme={null}
# Negotiation programme

[chip:6 sessions] [chip:Beginner,tone=accent]

Practise asking for what you are worth, from the first number to the final
handshake.

[plan-progress]

## Start here

[sessions:filter=negotiation-basics,limit=3]

[note:tip]
Do these in order — each one assumes the last.
[/note]

## Go deeper

[sessions:filter=negotiation-advanced]

[divider]

[button:See the whole catalogue,href=/catalogue,tone=accent]
```

## HTML

Plain HTML works for anything Markdown cannot express:

```markdown theme={null}
<div style="text-align: center">Centred</div>

Text with <span style="color: #b45309">a coloured word</span> in it.
```

Four things to know:

* `style` is written the ordinary HTML way, as a string. It is converted for you.
* `class`, `colspan`, `tabindex` and the rest of the HTML attribute names are accepted and translated.
* `onclick` and every other `on…` handler is removed, as are `javascript:` links. Content submitted through the API cannot run scripts in a candidate's browser.
* Void tags may be written either way — `<br>` and `<br />` both work.

## Things that trip people up

**Curly braces are safe.** `{name}` renders as `{name}`. You do not need to escape it.

**A block element must be alone on its line.** `Some text [sessions]` renders the literal text. Chips and `[kbd:…]` are the exception — those are inline by design.

**Unknown names stay as text.** `[see the guide]` on its own line renders as written, because `see the guide` is not one of the names above.

**Nothing inside a code fence is interpreted**, including the elements on this page. That is how you show the syntax to someone else.

**Values may contain spaces, but not commas.** `[button:Book a session,href=/x]` is fine; a label with a comma in it will be cut short.

**Backslashes in stored content are expected.** Content that was last saved through the JobMojito admin editor comes back with backslashes in front of punctuation — `\[sessions\:negotiation]`. That is the editor's own escaping and it renders correctly. Leave it as it is; do not strip it by hand.

**Close your containers.** An unclosed `[card]` wraps everything after it rather than blanking the page, but it will not look the way you meant.
