Point your AI at this page. It can reshape columns and settings, pull trades for analysis, add or update rows, clean up imports, and run formulas. That includes moving an old journal into JouView. Machine schema: /api/journal/openapi.json.
What your AI can do
All of this goes through https://jouview.com/api/journal/* (see the agent sections below and the OpenAPI schema).
Job
How
Add / change / remove columns
GET /api/journal/columns then PUT /api/journal/columns. Array order is the full grid order — include system names (Trade, Profit, …) where you want them. replaceCustom: false merges custom by name. true makes custom columns exactly your list (system always kept). Max 800 columns.
Handle settings
Column formulas, enums, cell styles on PUT /columns. Whole-row chrome via GET/PUT /api/journal/row-styles.
Retrieve data to analyse
GET /api/journal/entries?take=50 (max 500) plus GET /columns for layout. Combine with formula knowledge below for session stats.
Add rows
POST /api/journal/entries or POST /api/journal/entries/batch (max 200). Always set a stable externalId.
Update rows
Same as add: POST /entries with the same externalId (and import broker key) upserts that trade and rewrites fields / core prices.
Delete rows
The API doesn't have any per-row DELETE. Soft-delete all AI-imported rows with POST /api/journal/reset and "removeImportedEntries": true (only brokerKey=ai-transfer). Broker-synced trades stay. Then re-POST the rows that you want to keep.
Modify field data
Upsert the entry with the new fields{} map (and/or symbol, quantity, prices, times). Unknown column names are skipped and returned in unknownFields.
Snapshots
Prefer TradingView ids or external https URLs. Upload to JouView only when hosting is required (Trader is effectively unlimited).
Create a tokenUse the button below, then paste the token into your AI only if it can call APIs (see the prompt).
Ask your AI to personalizeCopy the prompt, fill in your task, and send it to any AI you use. Or attach CSVs/exports/screenshots to import an existing journal into JouView.
Refresh JouViewAfter the AI finishes, open the JouView menu (bottom tab) and press Refresh so the journal picks up the new columns, styles or changes.
Copy-paste prompt
I want you to modify my JouView journal via the Journal API.
Read https://jouview.com/ai-usage/
My token (keep private): <PASTE_jvtr_TOKEN>
What I want done:
<DESCRIBE_TASK>
Checking sign-in...
Usage recipes
Concrete tasks your AI should follow. Transferring an old journal is only one of them.
0. Before any write
GET firstGET /api/journal/columns and GET /api/journal/row-styles.
Quote what you foundList custom column names and whether row rules already exist. Never say the journal is empty unless those GETs show that.
Merge by defaultAdd columns with replaceCustom: false. For row styles, GET existing rules, then PUT the full merged list.
Default is merge (replaceCustom: false). To drop custom columns that aren't in your list, use "replaceCustom": true and "confirmReplaceCustom": true. Without the confirm flag, the API rejects a replace that would remove existing custom columns. System columns are never removed.
POST again with the sameexternalId and the corrected payload. Core fields and fields{} replace what you send.
6. Delete AI-imported trades
POST /api/journal/reset
{ "removeImportedEntries": true }
Only rows created through this API (ai-transfer) are removed. To delete a subset: reset imports, then re-POST the keepers with their original externalId values.
7. Example: transfer an existing journal
Read the specsThis page + GET /api/journal/openapi.json.
InspectGET /columns.
LayoutPUT /columns (+ optional PUT /row-styles).
ImportPOST /entries/batch with stable externalId per source row.
SnapshotsTradingView id, external URL, or upload.
VerifyGET /entries?take=10.
Rebuild if neededPOST /reset then recreate.
For AI agents: start here
Base URL: https://jouview.com
Authorization: Bearer jvtr_... (preferred)
Or query: ?access_token=jvtr_... (when you cannot set headers)
Token lifetime: at most 1 hour. Mint a fresh token if yours is older or rejected as legacy.
IP binding: the first IP that successfully uses the token owns it until expiry. Later calls from other IPs get 401.
Spec JSON: GET /api/journal/openapi.json (= /api/journal/schema)
Do not call api.jouview.com with raw userIds for this API. Only these /api/journal/* routes. Prefer Bearer. Use ?access_token= only when your tool cannot send Authorization. Keep all calls for one token on the same egress IP.
Column: a grid field. Custom columns hold playbook data (setup, checklist, tags). System columns are seeded by JouView.
fields{}: map of columnName → value on an entry. Unknown names are skipped and returned in unknownFields.
Computed cell: column with formula. The UI evaluates it. You usually don't need to also write fields[ThatColumn].
Cell style: per-column params: textColor, backgroundColor, bold, and so on.
Row style: rules from PUT /api/journal/row-styles. They apply to the whole row. Cell styles override per channel.
externalId: stable source id. Same externalId + import broker key upserts the same row.
System columns (read-only identity)
Created automatically. isSystem: true. You cannot rename, retype, or delete them via this API. You can reorder them by including their names in PUT /columns. Do not create custom columns with these names.
Name
Type
Default visible
Import note
Trade
actions
yes
Reserved UI. Never invent.
Date/Time
datetime
yes
From entryTime
Duration
number
yes
Usually computed
Price
number
yes
From entry/exit price
SL/TP
number
yes
Stops/targets UI
Symbol
text
no
Set symbol on entry
Lots/Qty
number
yes
Set quantity
RR
number
no
fields.RR or formula
Risk
number
yes
fields.Risk
Profit
number
yes
fields.Profit (common for history)
Cumulative profit
number
no
Usually UI-computed
Run-up / Drawdown / BE Run-up / Virtual*
number
mixed
Optional fields
Snapshots
actions
yes
Reserved
Notes
richtext
yes
fields.Notes
Column types & allowed JSON values
type
Aliases accepted
Field value examples
Enums?
text
string, note
"CBreak"
yes
richtext
notes
"Clean retest"
no
number
numeric, float, int
"420", "-180.5"
yes
bool
checkbox, boolean, yesno
"1"/"0" (also true/false/yes/no)
no
date
N/A
"2024-06-12"
yes
time
N/A
"14:32"
yes
datetime
N/A
"2024-06-12T14:32:00Z"
yes
stars
rating
"0"..."5" in 0.5 steps
no
group
N/A
container: use groupMembers
no
actions
N/A
system only. You can't create these.
no
Enums
enumValues: comma-separated choices, e.g. "CBreak, Impulse, Bias". Set enumMultiValue: true only if the user needs multi-select. Not allowed on bool / richtext / stars / group / actions.
Members hide from the main grid. Double-click opens them.
A column belongs to at most one group
Groups can't nest inside other groups
groupSummaryColumn must be one of the members
Chart snapshots
JouView's snapshot viewer stores a SnapshotUrl per image on a trade. Choose the lightest option that works:
TradingView (preferred when applicable): if the chart is already at https://tradingview.com/x/{id}, pass only the {id} suffix in snapshots[]. The viewer prefixes https://tradingview.com/x/. Full tradingview.com/x/... URLs are accepted and normalized to the id. These do not count toward the upload limit.
External https URL: any permanent image URL whose host is not jouview.com. Store the full URL as-is. It doesn't use any upload. It doesn't use any quota.
Upload to JouView: only when you must host the file on jouview.com (local file / private blob). That is the only case that uses the hosted-upload quota (Trader is effectively unlimited).
1. Upload the image file (only if hosting on JouView)
Max 10 MB per file. Types: png, jpg, jpeg, webp, gif. Public GET at the returned URL. TradingView ids and non-jouview.com https URLs do not consume quota. Trader hosted uploads are effectively unlimited.
Or include "snapshots": [ "..." ] on POST /api/journal/entries. replace: false appends. Attaching never increments the upload quota.
Endpoints
GET /api/journal/columns
List system + custom columns (full parameter dump).
PUT /api/journal/columns
replaceCustom: false merges custom by name. true makes custom columns exactly your list (system always kept). Array order is the journal column order for system + custom — include system names where you want them; omitted system columns stay and are appended. Max 800 columns.
Including a system name (e.g. Profit) reorders that column and can update visibility/styles — it does not create a second custom Profit. You cannot rename, retype, or delete system columns. Write values via fields.Profit.
GET /api/journal/row-styles · PUT /api/journal/row-styles
See Styles section. PUT body { "rules": [] } clears.
POST /api/journal/entries
Create or upsert one trade (same externalId updates).
{ "entries": [ ... ] } max 200. Response includes created, failed, results, errors[{index,error,symbol}].
POST /api/journal/snapshots/upload
multipart field file. Hosts the image on jouview.com (counts toward the plan upload quota; Trader is effectively unlimited). Prefer TradingView ids or external https URLs instead when possible.
PUT /api/journal/entries/{positionId}/snapshots
{ "snapshots": ["id-or-url",...], "replace": true }. TradingView /x/ id, external https URL, or JouView upload url. Attaching does not use upload quota.
created + errors[] (each item includes type/stack)
200
Unknown field names
unknownFields[] skipped
API failures return a JSON body with the exception message and context (type, path, method, traceId, stackTrace, innerExceptions). Use that when filing support reports.
Reusing externalId upserts. Changing it creates another row.
Only soft-deletes via reset affect brokerKey=ai-transfer rows. Broker-synced trades are left alone.
Column names max 50 chars. They must be unique per user (case-insensitive).
Tokens (agents): max 1 hour. Auth via Authorization: Bearer or ?access_token=. First successful call binds the token to that client IP for the rest of its life. Other IPs get 401. Legacy long-lived tokens are rejected.
Rate limits (429): per token user (else IP): schema 600/min, reads 1200/min, writes 400/min, uploads 100/min, token mint 100/hour, reset 60/hour. Response may include Retry-After.
Columns: max 800 per PUT, 800 custom, 1000 total with system. Max 400 value formulas and 800 style expressions per PUT. Each expression is <= 40000 chars.
Row styles: max 200 rules / 400 expressions.
Entries: max 2000 per batch. Field values are length-capped. Max 200 snapshots per trade.
Injection guard: formulas/styles reject host APIs (fetch, eval, document, window, and so on) and script-like patterns. Column names use a safe charset. The server rejects control characters.
Body size: JSON requests capped at 10 MB (uploads use the separate photo size limit).
Start again from scratch
POST /api/journal/reset
{
"removeCustomColumns": true,
"removeImportedEntries": true,
"clearRowStyles": true
}
Then PUT /columns with replaceCustom: true and re-import entries. Does not delete the JouView account. Set only the flags you need.
Formulas
Full formula language for computed cells, style channels, and row rules. Humans edit these in Settings → Journal columns → pen (or Row styles). AI agents set the same strings on PUT /columns / PUT /row-styles.
What a formula is
A formula is one JavaScript expression. It runs in a sandbox for a single journal row (and, when you ask for it, across other rows via ROWS). You attach formulas in Settings → Journal columns → pen:
Formula: the value the cell shows (custom columns only). System columns like Profit keep their own logic.
Style fields: bold, italic, underline, font size, text color, background, align. Each can be fixed or a formula.
Row styles use the same language for whole-trade chrome. Styles never change stored values.
Syntax
Column references: [Column name]. Names are not case-sensitive. Spacing matters: [Row number] works. [RowNumber] does not.
Maths: + - * / % and parentheses, e.g. ([A] + [B]) / 2.
Text: + joins strings. Put literals in quotes: "Long", not Long.
Choices: ternary only: condition ? whenTrue : whenFalse. JouView doesn't have any IF().
Comparisons: always === / !== (never a single =), plus < <= > >=, &&, ||, !.
JavaScript helpers: Math, Number, String, .toFixed, .includes, .split, Date.parse, arrow functions, and so on. The sandbox doesn't allow network, browser storage, or page DOM access.
Empty cells count as 0 when they look numeric to the engine. That keeps [A] + [B] arithmetic when one side is blank. When joining text that may be blank, write ([Notes] || "") + " - done".
The second example is a Bold/Italic condition: truthy turns the style on. Leave a style field blank to inherit the row rule (or the grid default). false / 0 turns Bold/Italic/Underline off.
Display format (numbers/dates) is a mask such as 0.00 or dd/mm/yyyy HH:mm. It changes how the value is shown, not what is stored.
Yes/No, dropdowns, multivalue
Yes/No columns compare as the text "true" / "false":
[Planned] === "true" ? 1 : 0
Dropdown values are set in the pen panel (comma-separated). Compare with === "A+". Tick Multivalue to allow several checked options. Then treat the cell as a comma list:
A Group column collapses several members into one journal cell (double-click to edit members). Its Formula can sum the members into a points total. A separate Stars column often maps that total onto 0-5:
Tune the min/max in the map to your real score range so a typical "good" trade lands around 4-5 stars.
Cross-row work with ROWS
ROWS is an array of every trade in the journal. Each element is an object keyed by column name (same names as [Brackets]). Use it for averages, streaks, session reviews, and account stats.
Arrow functions and .filter / .map / .reduce are the usual tools. Keep review rows out of averages with Setup tags such as session review / day review.
Build a checklist (power-user pattern)
Many small inputs → points → stars → optional review averages. Start small. Grow the point list over time.
1. Inputs: Yes/No or dropdown columns for each criterion (e.g. Planned, Retest, Liquidity). Optional Yes/No Checklist Done if you only want a score after finishing the list.
2. Direction helper
// Column "Bias"
[Trade] === "Long" ? 1 : -1
3. Points group: Group (or number) column whose Formula adds weighted signals:
A cell that cannot be evaluated shows ERR. Hover it: the tooltip names the problem, lists every referenced value with its type, and suggests a fix. Common causes:
Single = instead of ===
Missing quotes around text
Calling a string method on a number (or the reverse). Wrap with String(...) / Number(...).
Referring to a column that was renamed
A circular reference between formula columns
After you save a formula it can take a moment to appear. Open JouView → How to on the chart for the live field list of your columns.
Live machine schema
Agents should fetch and follow this JSON (includes OpenAPI-style paths, components.schemas, catalogs, workflows):
Open the JouView menu (bottom tab) and press Refresh so the journal picks up the new columns, styles or changes. Then confirm the journal and adjust anything in Settings.