---
title: Yadulink agent authentication
description: How AI agents obtain and use Yadulink credentials: scoped API keys for the REST API, OAuth 2.0 with PKCE for the MCP server.
canonical: https://yadulink.com/auth.md
last-updated: 2026-07-25
---

# auth.md

This document tells agents how to obtain credentials for Yadulink.
The REST API resource server is `https://app.yadulink.com` and the OAuth authorization
server is `https://app.yadulink.com`. The MCP resource server is `https://mcp.yadulink.com`.

## Discover

1. REST API metadata: `https://yadulink.com/.well-known/oauth-protected-resource`
   (scopes_supported lists every API scope). The OpenAPI contract is
   `https://yadulink.com/api/v1/openapi.json`.
2. MCP metadata: `https://mcp.yadulink.com/.well-known/oauth-protected-resource/mcp`, then follow
   `authorization_servers` to `https://app.yadulink.com/.well-known/oauth-authorization-server`.

## Pick a method

| You are | Use |
| --- | --- |
| A script, workflow tool (n8n, Zapier, Make), or backend agent | Scoped API key (Bearer) |
| An interactive MCP client acting for a signed-in user | OAuth 2.0 authorization code + PKCE |

## Register - API key (human-in-the-loop)

API keys cannot be provisioned anonymously. Ask the account owner to create one:

1. Sign in at `https://app.yadulink.com` and open Integrations > API keys.
2. Create a key with the minimal scopes for the job (for example `leads:read`).
3. Send it on every request:

```http
GET /api/v1/me HTTP/1.1
Host: app.yadulink.com
Authorization: Bearer yd_your_key
```

## Register - OAuth client (dynamic)

MCP clients register dynamically (RFC 7591), no portal step required:

```http
POST /oauth/register HTTP/1.1
Host: app.yadulink.com
Content-Type: application/json

{"client_name": "My agent", "redirect_uris": ["https://client.example/callback"],
 "grant_types": ["authorization_code", "refresh_token"], "token_endpoint_auth_method": "none"}
```

Then run the authorization-code flow with PKCE (S256) at `/oauth/authorize` and
`/oauth/token`. The signed-in user reviews and approves the requested scopes.

## Use the access token

- REST API: `Authorization: Bearer yd_...` against `https://app.yadulink.com/api/v1`.
- MCP: `Authorization: Bearer <access_token>` against `https://mcp.yadulink.com/mcp`.
- Refresh MCP tokens at `/oauth/token` with `grant_type=refresh_token`.

## Scopes

- `account:read`: Read account status, limits, and subscription state.
- `connections:write`: Send LinkedIn connection requests through action jobs.
- `credits:read`: Read API credit balance, ledger, and price table.
- `jobs:read`: Read asynchronous action job status.
- `jobs:write`: Create and cancel asynchronous action jobs.
- `leads:read`: Read leads and lead search results.
- `leads:write`: Create, update, and delete leads.
- `lists:read`: Read lead lists and their contents.
- `lists:write`: Create, update, and delete lead lists.
- `mcp:self:content:read`: MCP: read feeds, signals, publications, audiences, and content statistics.
- `mcp:self:content:write`: MCP: manage publications and run confirmed LinkedIn content actions.
- `mcp:self:credits:read`: MCP: read the monthly API-credit balance and operation prices.
- `mcp:self:messages:read`: MCP: read and summarize the connected LinkedIn inbox.
- `mcp:self:messages:write`: MCP: send explicitly confirmed messages in owned LinkedIn conversations.
- `mcp:self:outreach:read`: MCP: audit lists, sequences, and contact priorities.
- `mcp:self:outreach:write`: MCP: run controlled outreach actions.
- `mcp:self:profile:read`: MCP: read the connected account profile and progress.
- `messages:read`: Read LinkedIn conversation history synced to Yadulink.
- `messages:write`: Send LinkedIn messages through action jobs.
- `posts:write`: Publish or interact with LinkedIn posts through action jobs.
- `profiles:write`: Visit LinkedIn profiles through action jobs.
- `webhooks:manage`: Create, update, and delete webhook endpoints.

## Errors

| Code | Endpoint | What to do |
| --- | --- | --- |
| `api_key_required` (401) | /api/v1/* | Add `Authorization: Bearer yd_...`. |
| `invalid_api_key` (401) | /api/v1/* | The key is unknown or revoked; ask the owner for a new one. |
| `insufficient_scope` (403) | /api/v1/* | Request a key or grant with the scope named in the error. |
| `rate_limited` (429) | /api/v1/* | Respect `Retry-After` and the `RateLimit` headers. |
| `invalid_client` (400) | /oauth/* | Re-register the OAuth client. |

## Revocation

- API keys: revoked from Integrations > API keys (owner action).
- OAuth tokens: `POST /oauth/revoke`, or the user revokes the authorization in the app.
