Skip to content
Text Post API

Module 01 · foundations · beginner

Exercises 01 · Text Post API

Start from workflow/starter.json (a linear Webhook → Build Post → Respond, with no validation: every request "creates" a post, even an empty one).

Exercise 1: Reject empty posts

Task: Add an IF node so requests without a text take a different path.

Done when: curl ... -d '{}' returns a different body than -d '{"text":"Shipped my first n8n API"}'.

Hint

Put the IF between the Webhook and Build Post. Check {{ $json.body.text }} with the is not empty operator.

Exercise 2: Return proper status codes

Task: Make a created post return HTTP 201, and a rejected one return 400 with {"error":"text must be 1-280 characters"}.

Done when: a valid post shows 201 and curl -d '{}' shows 400 (add -w '%{http_code}' to see the code).

Hint

You need two Respond to Webhook nodes, one per branch. The status code is under Options → Response Code, on each node.

Exercise 3: Enforce the 280-character limit

Task: Reject posts longer than 280 characters with the same 400 error.

Done when: ./test/test.sh passes all five checks.

Hint

Add a second condition to the same IF, combined with AND: {{ ($json.body.text || '').length }} is less than or equal to 280 (Number). The || '' keeps it from failing when text is missing.

Exercise 4: Go to production

Task: Publish the workflow and call the production URL instead of the test URL.

Done when: curl -X POST http://localhost:5678/webhook/posts ... works without clicking Listen, and the run shows in the Executions tab.

Hint

The production path is /webhook/, not /webhook-test/.

Stretch: Pull out hashtags

Task: Add a hashtags array to the created post, e.g. "Shipping #n8n #nocode" returns ["n8n","nocode"].

Hint

Add a field of type Array in Build Post. String.match() with a regex finds every #word; remember it returns null when there are none.