PrismDraft SDK

links

The methods of pd.links. Inputs and outputs are described in Conventions; every method can also fail as described in Errors.

Methods

pd.links.list(input, init?)

Internal link suggestions for an article

GET /api/articles/{articleId}/links

Returns every link suggestion generated for the article, whatever its status (pending, accepted, rejected), newest first, each with the title and slug of the article it points at. Requires articles.read. It does not depend on the internal_linking_automation flag.

Input

Name In Type Required Description
articleId path string (uuid) yes Id of an article. The workspace and project it belongs to are read from the article, never from the request; the caller must be a member of that workspace (and of the project, when it has members). For anyone else the answer is 404 RESOURCE_NOT_FOUND, the same as for an id that does not exist.
init init { signal?: AbortSignal; timeoutMs?: number } no The second argument: signal aborts the call, timeoutMs overrides the client's per-attempt timeout.

Returns 200 OK

Field Type Required Description
suggestions object[] yes Every suggestion for the article whatever its status, newest first.
suggestions[].id string (uuid) yes Id of the link suggestion.
suggestions[].workspaceId string (uuid) yes Id of the workspace that owns the suggestion.
suggestions[].sourceArticleId string (uuid) yes Id of the article the link would be written into: the one that was analysed.
suggestions[].targetArticleId string (uuid) yes Id of the article the link would point to.
suggestions[].anchorText string yes The words in the source article that would become the link. Accepting looks for this text, exactly as written, in a paragraph or quote.
suggestions[].reason string yes Why the model suggested this link. An empty string when none.
suggestions[].status "pending" | "accepted" | "rejected" yes Where the suggestion stands: pending (not decided; nothing has been changed in the article), accepted (the link was written into the source article) or rejected (declined; the article was not touched).
suggestions[].createdAt string (date-time) yes When the suggestion was generated, as an ISO 8601 UTC date-time.
suggestions[].updatedAt string (date-time) yes When the suggestion was last decided or edited, as an ISO 8601 UTC date-time.
suggestions[].target object yes The article the link would point to.
suggestions[].target.id string (uuid) yes Id of the target article; the same as targetArticleId.
suggestions[].target.title string yes Current title of the target article.
suggestions[].target.slug string yes Current slug of the target article, unique within its project and language.

Errors 400 invalid input, 401 missing or invalid key, 403 the key's roles lack the permission, 404 not found, 429 rate limited or out of quota. See Errors.

Example

import { PrismDraft } from "@prism-draft/sdk";

const pd = new PrismDraft({ apiKey: process.env.PRISMDRAFT_API_KEY! });

const result = await pd.links.list({
  articleId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);

pd.links.generate(input, init?)

Generate internal link suggestions

POST /api/articles/{articleId}/links

Asks the model which of the project's other published articles in the same language (at most 50 candidates) the article could link to, from the first 6,000 characters of its text, and stores up to 10 suggestions as pending; none is applied until links.decide. Requires articles.update; behind the internal_linking_automation feature flag, and 400 INVALID_REQUEST when the flag is off or the article has no text. With no candidate it answers at once with an empty list and no model call; otherwise it costs no credits but counts against the ai_operations quota (429 QUOTA_EXCEEDED). A pair of source and target already suggested, whatever its status, is not added again, so a rejected pair never comes back. The anchor is requested to appear in the article but is not checked: accepting a suggestion whose anchor does not appear answers 409.

Input

Name In Type Required Description
articleId path string (uuid) yes Id of an article. The workspace and project it belongs to are read from the article, never from the request; the caller must be a member of that workspace (and of the project, when it has members). For anyone else the answer is 404 RESOURCE_NOT_FOUND, the same as for an id that does not exist.
init init { signal?: AbortSignal; timeoutMs?: number } no The second argument: signal aborts the call, timeoutMs overrides the client's per-attempt timeout.

Returns 200 OK

Field Type Required Description
suggestions object[] yes Every suggestion for the article whatever its status, newest first.
suggestions[].id string (uuid) yes Id of the link suggestion.
suggestions[].workspaceId string (uuid) yes Id of the workspace that owns the suggestion.
suggestions[].sourceArticleId string (uuid) yes Id of the article the link would be written into: the one that was analysed.
suggestions[].targetArticleId string (uuid) yes Id of the article the link would point to.
suggestions[].anchorText string yes The words in the source article that would become the link. Accepting looks for this text, exactly as written, in a paragraph or quote.
suggestions[].reason string yes Why the model suggested this link. An empty string when none.
suggestions[].status "pending" | "accepted" | "rejected" yes Where the suggestion stands: pending (not decided; nothing has been changed in the article), accepted (the link was written into the source article) or rejected (declined; the article was not touched).
suggestions[].createdAt string (date-time) yes When the suggestion was generated, as an ISO 8601 UTC date-time.
suggestions[].updatedAt string (date-time) yes When the suggestion was last decided or edited, as an ISO 8601 UTC date-time.
suggestions[].target object yes The article the link would point to.
suggestions[].target.id string (uuid) yes Id of the target article; the same as targetArticleId.
suggestions[].target.title string yes Current title of the target article.
suggestions[].target.slug string yes Current slug of the target article, unique within its project and language.
created integer yes How many suggestions this call added. A source and target pair that was suggested before, whatever its status, is not added again.

Errors 400 invalid input, 401 missing or invalid key, 403 the key's roles lack the permission, 404 not found, 429 rate limited or out of quota. See Errors.

Example

import { PrismDraft } from "@prism-draft/sdk";

const pd = new PrismDraft({ apiKey: process.env.PRISMDRAFT_API_KEY! });

const result = await pd.links.generate({
  articleId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);

pd.links.decide(input, init?)

Accept, edit or reject a link suggestion

POST /api/workspaces/{workspaceId}/links/{suggestionId}

Decides one suggestion; requires articles.update on the source article's project, and 404 when the suggestion is not in the workspace. rejected only records the refusal. accepted writes the link into the source article and sets the status in one transaction: the anchor is looked up, exactly as written, in the first plain-text paragraph or quote that contains it, and the article gets a new version; 409 CONFLICT (anchor_not_found) when no block does, so edit it first with anchorText. Accepting again with the same anchor changes nothing, a different anchor adds a second link, and rejecting afterwards does not remove a written link. An acceptance records an articles.updated audit entry and, when the article is published, emits the article.updated webhook event.

Input

Name In Type Required Description
workspaceId path string (uuid) yes Id of the workspace the request works in. The caller must be a member of it, or hold an API key issued by it. For anyone else, an unknown id and an id they do not belong to both answer 404 RESOURCE_NOT_FOUND, so membership cannot be probed.
suggestionId path string (uuid) yes Id of the link suggestion, in the workspace workspaceId; read from links.list. 404 when it is not.
body body object yes
body.decision body "accepted" | "rejected" yes accepted writes the link into the source article; rejected only records the refusal and leaves the article as it is.
body.anchorText body string no The words to turn into the link, 1 to 300 characters, replacing the suggestion's own anchorText; the new value is stored on the suggestion. Absent: the suggested anchor is used.
init init { signal?: AbortSignal; timeoutMs?: number } no The second argument: signal aborts the call, timeoutMs overrides the client's per-attempt timeout.

Returns 200 OK

Field Type Required Description
suggestion object yes The suggestion after the decision.
suggestion.id string (uuid) yes Id of the link suggestion.
suggestion.workspaceId string (uuid) yes Id of the workspace that owns the suggestion.
suggestion.sourceArticleId string (uuid) yes Id of the article the link would be written into: the one that was analysed.
suggestion.targetArticleId string (uuid) yes Id of the article the link would point to.
suggestion.anchorText string yes The words in the source article that would become the link. Accepting looks for this text, exactly as written, in a paragraph or quote.
suggestion.reason string yes Why the model suggested this link. An empty string when none.
suggestion.status "pending" | "accepted" | "rejected" yes Where the suggestion stands: pending (not decided; nothing has been changed in the article), accepted (the link was written into the source article) or rejected (declined; the article was not touched).
suggestion.createdAt string (date-time) yes When the suggestion was generated, as an ISO 8601 UTC date-time.
suggestion.updatedAt string (date-time) yes When the suggestion was last decided or edited, as an ISO 8601 UTC date-time.

Errors 400 invalid input, 401 missing or invalid key, 403 the key's roles lack the permission, 404 not found, 429 rate limited or out of quota. See Errors.

Example

import { PrismDraft } from "@prism-draft/sdk";

const pd = new PrismDraft({ apiKey: process.env.PRISMDRAFT_API_KEY! });

const result = await pd.links.decide({
  workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
  suggestionId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
  body: {
    decision: "accepted",
  },
});
console.log(result);