Calling the API from backend JavaScript
The JavaScript of a backend module can call the API with the module
@typo3/core/action/request. You need no app and no token of your own: the
request uses the session of the logged-in backend user, so the permissions of
this user apply. The action must have the target Target::backend, see
Targets. The record and file actions have this target.
The module is for the TYPO3 backend only. An external application uses the HTTP API with a token, see Authentication.
Import action in an ES module of your extension. Register the
module in Configuration/JavaScriptModules.php of your extension,
as for all backend JavaScript.
import { action } from '@typo3/core/action/request.js';The first argument is the path of the action with its version, without
/typo3/api. The function adds this prefix. The second argument gives
the values of the placeholders in the path, for example {uid}.
resolve() returns the result as JSON.
const request = action('/v1/records/{schema}/{identifier}', {
schema: 'pages',
identifier: '3',
});
const response = await request.get();
const { record } = await response.resolve();To send query parameters, use withQueryArguments():
const request = action('/v1/records/{schema}', {
schema: 'pages',
});
const response = await request
.withQueryArguments({ limit: 10 })
.get();
const { items, next } = await response.resolve();action() returns an AjaxRequest of TYPO3. It has the methods
get(), post(), put(), patch() and
delete(). For a JSON body, set the header Content-Type:
await action('/v1/records/{schema}/{identifier}', {
schema: 'pages',
identifier: '3',
}).patch(
{ record: { _schema: 'pages', title: 'New title' } },
{ headers: { 'Content-Type': 'application/json' } },
);If the status is not 2xx, the request throws the response. The
body is problem details with the content type
application/problem+json, so call resolve('json'). See
Responses and errors.
try {
await action('/v1/records/{schema}/{identifier}', {
schema: 'pages',
identifier: '999999',
}).get();
} catch (response) {
const problem = await response.resolve('json');
console.error(response.raw().status, problem.detail);
// 404 Record not found
}Import action in an ES module of your extension. Register the
module in Configuration/JavaScriptModules.php of your extension,
as for all backend JavaScript.
import { action } from '@typo3/core/action/request.js';Import the function
Import action in an ES module of your extension. Register the
module in Configuration/JavaScriptModules.php of your extension,
as for all backend JavaScript.
import { action } from '@typo3/core/action/request.js';import { action } from '@typo3/core/action/request.js';
The first argument is the path of the action with its version, without
/typo3/api. The function adds this prefix. The second argument gives
the values of the placeholders in the path, for example {uid}.
resolve() returns the result as JSON.
const request = action('/v1/records/{schema}/{identifier}', {
schema: 'pages',
identifier: '3',
});
const response = await request.get();
const { record } = await response.resolve();To send query parameters, use withQueryArguments():
const request = action('/v1/records/{schema}', {
schema: 'pages',
});
const response = await request
.withQueryArguments({ limit: 10 })
.get();
const { items, next } = await response.resolve();Read data
The first argument is the path of the action with its version, without
/typo3/api. The function adds this prefix. The second argument gives
the values of the placeholders in the path, for example {uid}.
resolve() returns the result as JSON.
const request = action('/v1/records/{schema}/{identifier}', {
schema: 'pages',
identifier: '3',
});
const response = await request.get();
const { record } = await response.resolve();const request = action('/v1/records/{schema}/{identifier}', {
schema: 'pages',
identifier: '3',
});
const response = await request.get();
const { record } = await response.resolve();
To send query parameters, use withQueryArguments():
const request = action('/v1/records/{schema}', {
schema: 'pages',
});
const response = await request
.withQueryArguments({ limit: 10 })
.get();
const { items, next } = await response.resolve();const request = action('/v1/records/{schema}', {
schema: 'pages',
});
const response = await request
.withQueryArguments({ limit: 10 })
.get();
const { items, next } = await response.resolve();
action() returns an AjaxRequest of TYPO3. It has the methods
get(), post(), put(), patch() and
delete(). For a JSON body, set the header Content-Type:
await action('/v1/records/{schema}/{identifier}', {
schema: 'pages',
identifier: '3',
}).patch(
{ record: { _schema: 'pages', title: 'New title' } },
{ headers: { 'Content-Type': 'application/json' } },
);Change data
action() returns an AjaxRequest of TYPO3. It has the methods
get(), post(), put(), patch() and
delete(). For a JSON body, set the header Content-Type:
await action('/v1/records/{schema}/{identifier}', {
schema: 'pages',
identifier: '3',
}).patch(
{ record: { _schema: 'pages', title: 'New title' } },
{ headers: { 'Content-Type': 'application/json' } },
);await action('/v1/records/{schema}/{identifier}', {
schema: 'pages',
identifier: '3',
}).patch(
{ record: { _schema: 'pages', title: 'New title' } },
{ headers: { 'Content-Type': 'application/json' } },
);
If the status is not 2xx, the request throws the response. The
body is problem details with the content type
application/problem+json, so call resolve('json'). See
Responses and errors.
try {
await action('/v1/records/{schema}/{identifier}', {
schema: 'pages',
identifier: '999999',
}).get();
} catch (response) {
const problem = await response.resolve('json');
console.error(response.raw().status, problem.detail);
// 404 Record not found
}Handle errors
If the status is not 2xx, the request throws the response. The
body is problem details with the content type
application/problem+json, so call resolve('json'). See
Responses and errors.
try {
await action('/v1/records/{schema}/{identifier}', {
schema: 'pages',
identifier: '999999',
}).get();
} catch (response) {
const problem = await response.resolve('json');
console.error(response.raw().status, problem.detail);
// 404 Record not found
}try {
await action('/v1/records/{schema}/{identifier}', {
schema: 'pages',
identifier: '999999',
}).get();
} catch (response) {
const problem = await response.resolve('json');
console.error(response.raw().status, problem.detail);
// 404 Record not found
}
The session cookie alone is not enough. The module also sends a bearer token, which the backend adds to its document for the logged-in user. The token must belong to the user of the session. This prevents that other websites call actions in the name of a logged-in backend user.
The session cookie alone is not enough. The module also sends a bearer token, which the backend adds to its document for the logged-in user. The token must belong to the user of the session. This prevents that other websites call actions in the name of a logged-in backend user.