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

# Full Integration Workflow

> Build a production-ready Phrase TMS plugin with resilient import, monitoring, export, and operations.

This guide extends Quick Start with production behavior and optional capabilities.

## At a glance

Recommended implementation order:

1. Authentication and token refresh
2. Import (project/job creation)
3. Monitoring (webhook-first)
4. Export and `DELIVERED` status
5. Optional extensions and hardening

## Prerequisites

* Completed [Quick Start](/en/guides/build-a-tms-plugin/quick-start).
* Phrase TMS project template(s) aligned to your workflow.
* Platform and TMS API base URLs for your tenant/region.
* Secure storage for API token and runtime secrets.
* A callback/webhook endpoint if you use push-based progress handling.

<Tip>If you only need a baseline production flow, implement sections 1-4 first. Sections 5+ are optional hardening and scaling improvements.</Tip>

## 1) Authentication strategy

* Base flow: `POST ${PLATFORM_BASE_URL}/idm/oauth/token` (token exchange).
* Include `Authorization: Bearer <access_token>` on API requests.
* Refresh on expiry and on a single retry after `401`.

<Note>For production, cache token expiry and centralize token refresh to avoid refresh storms under load.</Note>

Reference:

* [Platform authentication](/en/api/platform/authentication)
* [OAuth token endpoint](/en/api/platform/oauth/token-endpoint)

## 2) Import content into TMS

### Required path

1. List templates: `GET /api2/v1/projectTemplates`
2. Create project: `POST /api2/v2/projects/applyTemplate/{templateUid}`
3. Create jobs: `POST /api2/v1/projects/{projectUid}/jobs`

Persist `templateUid`, `projectUid`, `job.uid`, and relevant `asyncRequest.id` values.
<Note>Need payload examples while implementing? Jump to <a href="#optional-reference-payloads-and-endpoint-map">Optional reference: payloads and endpoint map</a>.</Note>

### Live preview integration point (optional)

If you use live preview, integrate it in this import phase:

1. Upload a preview package after project creation.
2. Store the returned preview package file UID.
3. Include `jobPreviewPackageFileUidRef` when creating the job.

See [Live Preview](/en/guides/build-a-tms-plugin/live-preview) for implementation details and failure handling.

### Optional path: expose content listing/download endpoints

If your integration uses TMS pull behavior from the third-party system:

* Expose a **list endpoint** to return selectable content.
* Expose a **download endpoint** to return encoded content for import.
* Validate auth and return clear HTTP errors for invalid requests.

<Tip>Keep endpoint responses deterministic. Stable IDs and filenames reduce duplicate imports and debugging complexity.</Tip>

Reference:

* [List project templates](/en/api/tms/latest/project-template/list-project-templates)
* [Create project from template](/en/api/tms/latest/project/create-project-from-template)
* [Create job](/en/api/tms/latest/job/create-job)

### Optional workflow extensions

If your lifecycle requires vendor automation and PM workflow support, add these operations after job creation:

* Assign providers from template: `POST /api2/v1/projects/{projectUid}/applyTemplate/{templateUid}/assignProviders`
* Create analyses by providers: `POST /api2/v1/analyses/byProviders`
* Notify assigned users: `POST /api2/v1/projects/{projectUid}/jobs/notifyAssigned`

Reference:

* [Assign providers from template](/en/api/tms/latest/project/assigns-providers-from-template)
* [Create analyses by providers](/en/api/tms/latest/analysis/create-analyses-by-providers)
* [Notify assigned users](/en/api/tms/latest/job/notify-assigned-users)

## 3) Monitor job progress

Use this priority order:

1. **Webhooks (recommended for production)**
2. **Async request status polling**
3. **Job-part polling fallback**

### Webhooks

* Configure webhook subscriptions for job/part/async lifecycle events.
* Verify sender token/header.
* Store events idempotently, acknowledge quickly, and process asynchronously.

### Async status

* Poll `GET /api2/v1/async/{asyncRequestId}` for completion when the workflow uses async endpoints.

### Callback pattern (alternative to polling)

Many async endpoints support `callbackUrl`.

* Callback payload includes async request metadata and action result.
* Callback endpoint should validate sender, persist event, and return `200` quickly.
* If callback URL is unreachable, Phrase retries after 2, 4, 8, 16, and 30 minutes (up to 10 failed retries).
* Callback delivery is considered successful only when your endpoint returns HTTP `200`.

Callback handler pseudocode:

```text theme={null}
POST /callbacks/phrase-async
  verifySignatureOrToken(request)
  event = parseJson(request.body)
  saveEventIdempotently(event.asyncRequest.id)
  enqueueAsyncProcessing(event)
  return 200
```

### Job-part status fallback

* Poll `GET /api2/v1/projects/{projectUid}/jobs/{jobUid}/parts` with backoff and jitter.

Reference:

* [Get asynchronous request](/en/api/tms/latest/async-request/get-asynchronous-request)
* Job parts endpoint: `GET /api2/v1/projects/{projectUid}/jobs/{jobUid}/parts`
* [Webhooks (support article)](https://support.phrase.com/hc/en-us/articles/5709693398812-Webhooks-TMS)

## Job status reference

Use this table to map statuses to plugin behavior.

| Status          | Typical phase             | Meaning                                           | Plugin action                          |
| --------------- | ------------------------- | ------------------------------------------------- | -------------------------------------- |
| `NEW`           | Creation / pre-assignment | Job exists and is not yet accepted                | Keep monitoring and surface as queued  |
| `ACCEPTED`      | Assignment                | Provider accepted the job                         | Continue monitoring workflow progress  |
| `DECLINED`      | Assignment                | Provider declined the job                         | Reassign provider or notify operator   |
| `COMPLETED`     | Completion                | Translation workflow is complete                  | Start export flow                      |
| `DELIVERED`     | Post-export               | Target content was exported/imported successfully | Treat as terminal success              |
| `CANCELLED`     | Exception                 | Work was stopped before completion                | Treat as terminal failure              |
| `REJECTED`      | Exception / QA            | Output was rejected and needs rework              | Route for rework, do not deliver       |
| `JOB_NOT_READY` | Import exception          | Job creation/import did not complete correctly    | Inspect import errors and retry safely |

## 4) Export translated content

### Pull from TMS via API

1. Start async export: `PUT /api2/v3/projects/{projectUid}/jobs/{jobUid}/targetFile`
2. Wait for completion via webhook/callback/polling.
3. Download file once ready: `GET /api2/v2/projects/{projectUid}/jobs/{jobUid}/downloadTargetFile/{asyncRequestId}`
4. Import result into third-party system.
5. Set terminal status: `POST /api2/v1/projects/{projectUid}/jobs/{jobUid}/setStatus` with `DELIVERED`.

### Push from TMS to your plugin (optional)

Expose a secure endpoint to receive translated payloads and run your import mapping there.

<Note>`asyncRequestId` for download is single-use. Persist and consume it carefully.</Note>

Reference:

* [Download target file async](/en/api/tms/latest/job/download-target-file-async-1)
* [Download target file by async request](/en/api/tms/latest/job/download-target-file-based-on-async-request)
* [Edit job status](/en/api/tms/latest/job/edit-job-status)

## 5) Continuous updates (optional, high-change workflows)

For continuous localization, update source content on existing jobs and re-run the workflow:

* Use `POST /api2/v1/projects/{projectUid}/jobs/source`
* Monitor completion using callbacks, webhooks, or async polling.
* Re-export translated output when updates finish.

Reference:

* [Update source](/en/api/tms/latest/job/update-source)

## 6) Metadata and reporting

Send plugin metadata in the Memsource header payload when creating jobs:

```json theme={null}
{
  "sourceData": {
    "clientType": "MY_PLUGIN",
    "clientVersion": "1.2.4",
    "hostVersion": "4.5.2"
  }
}
```

* `clientType` is required and must be registered with Phrase.
* `clientVersion` and `hostVersion` are optional.

## 7) Idempotency implementation guidance

Implement idempotency for all create and delivery operations:

| Operation                   | Recommended idempotency key                   |
| --------------------------- | --------------------------------------------- |
| Create project              | External content batch ID + template ID       |
| Upload/create job           | Source content checksum + locale + project ID |
| Start export                | Job ID + source revision                      |
| Download/import target file | Async request ID + target system item ID      |
| Update status (`DELIVERED`) | Job ID + delivered revision                   |

Pattern:

1. Build deterministic operation key before API call.
2. Check/store key in durable storage with operation state.
3. If duplicate key appears, return previously stored result instead of replaying.

## 8) Logging field specification

Log these fields for every API call and lifecycle event:

| Field                 | Why it matters                              |
| --------------------- | ------------------------------------------- |
| `timestamp`           | Event ordering and latency analysis         |
| `requestId`           | Tie plugin logs to HTTP calls               |
| `correlationId`       | Trace a single localization flow end-to-end |
| `projectUid`          | Project-level troubleshooting               |
| `jobUid`              | Job-level troubleshooting                   |
| `asyncRequestId`      | Async lifecycle correlation                 |
| `pluginInstanceId`    | Multi-instance debugging                    |
| `endpoint` + `method` | API behavior visibility                     |
| `statusCode`          | Error and retry analytics                   |
| `durationMs`          | Performance and SLO measurement             |

## Plugin variants

| Capability                | Canonical plugin | Live content plugin | Continuous localization plugin |
| ------------------------- | ---------------- | ------------------- | ------------------------------ |
| Token exchange + refresh  | Must             | Must                | Must                           |
| Project from template     | Must             | Must                | Must                           |
| Webhooks                  | Should           | Must                | Must                           |
| Live preview              | Can              | Must                | Can                            |
| Idempotent source updates | Should           | Must                | Must                           |
| Advanced observability    | Should           | Must                | Must                           |

## Operational hardening checklist

* Retry transient errors (`429`, `5xx`) with exponential backoff + jitter.
* Avoid duplicate create/export actions with idempotency keys or dedupe logic.
* Log correlation IDs, project/job IDs, endpoint, status, and latency.
* Track success rates and error rates for create/monitor/export operations.
* Add alerts for repeated failures and webhook delivery issues.

## Testing expectations

* Happy path: create → monitor → export → `DELIVERED`.
* Failure path: auth errors, validation errors, rate limits, service errors.
* Resilience path: webhook miss + polling fallback.
* Update path (if enabled): source updates and repeated export.

## Optional reference: payloads and endpoint map

### Core payload snippets

Create project from template request:

```json theme={null}
{
  "name": "Website Translation",
  "sourceLang": "en",
  "targetLangs": ["de", "fr"]
}
```

Create project from template response (excerpt):

```json theme={null}
{
  "uid": "proj-uid-1",
  "name": "Website Translation",
  "status": "NEW",
  "sourceLang": "en",
  "targetLangs": ["de", "fr"]
}
```

Create job response (excerpt):

```json theme={null}
{
  "jobs": [
    {
      "uid": "job-uid-1",
      "status": "NEW",
      "targetLang": "de"
    }
  ],
  "asyncRequest": {
    "id": "async-req-1",
    "action": "PRE_ANALYSE"
  }
}
```

Set job status request:

```json theme={null}
{
  "requestedStatus": "DELIVERED",
  "notifyOwner": true,
  "propagateStatus": true
}
```

### Endpoint reference glossary

| Action                                    | Method | Endpoint                                                                           |
| ----------------------------------------- | ------ | ---------------------------------------------------------------------------------- |
| Exchange API token for access token       | `POST` | `${PLATFORM_BASE_URL}/idm/oauth/token`                                             |
| List project templates                    | `GET`  | `/api2/v1/projectTemplates`                                                        |
| Create project from template              | `POST` | `/api2/v2/projects/applyTemplate/{templateUid}`                                    |
| Create job                                | `POST` | `/api2/v1/projects/{projectUid}/jobs`                                              |
| Assign providers from template            | `POST` | `/api2/v1/projects/{projectUid}/applyTemplate/{templateUid}/assignProviders`       |
| Create analyses by providers              | `POST` | `/api2/v1/analyses/byProviders`                                                    |
| Notify assigned users                     | `POST` | `/api2/v1/projects/{projectUid}/jobs/notifyAssigned`                               |
| Get async request                         | `GET`  | `/api2/v1/async/{asyncRequestId}`                                                  |
| List job parts                            | `GET`  | `/api2/v1/projects/{projectUid}/jobs/{jobUid}/parts`                               |
| Start async target-file export            | `PUT`  | `/api2/v3/projects/{projectUid}/jobs/{jobUid}/targetFile`                          |
| Download target file by async request     | `GET`  | `/api2/v2/projects/{projectUid}/jobs/{jobUid}/downloadTargetFile/{asyncRequestId}` |
| Set job status                            | `POST` | `/api2/v1/projects/{projectUid}/jobs/{jobUid}/setStatus`                           |
| Update source for continuous localization | `POST` | `/api2/v1/projects/{projectUid}/jobs/source`                                       |

<Note>For complete request/response schemas, use the linked endpoint pages and the [TMS API reference](/en/api/tms/latest/introduction).</Note>

## Additional resources

* Postman collection for rapid API validation and manual flow testing.
* [TMS API reference](/en/api/tms/latest/introduction) for full payload schemas.
* [Webhooks support guide](https://support.phrase.com/hc/en-us/articles/5709693398812-Webhooks-TMS) for account-level event setup and retries.

## Next steps

<CardGroup cols={3}>
  <Card title="Live Preview" icon="monitor" href="/en/guides/build-a-tms-plugin/live-preview">
    Add context-rich in-editor preview behavior.
  </Card>

  <Card title="Error Handling & Limits" icon="shield-alert" href="/en/guides/build-a-tms-plugin/error-handling-and-limits">
    Confirm failure handling and limit-safe behavior.
  </Card>

  <Card title="API Reference (TMS Latest)" icon="book-open" href="/en/api/tms/latest/introduction">
    Review endpoint-level request and response details.
  </Card>
</CardGroup>
