Developer
News and Updates
Get Support
Sign in
Get Support
Sign in
DOCUMENTATION
Cloud
Data Center
Resources
Sign in
Sign in
DOCUMENTATION
Cloud
Data Center
Resources
Sign in
Last updated Nov 24, 2025

setRelationships

The Connector SDK APIs are available through Forge's Early Access Program (EAP).

EAPs are offered to selected users for testing and feedback purposes. We are currently working with a select group of EAP participants to get their apps production-ready and available for publishing on Marketplace.

To use the Connector SDK, you must be part of the Forge connector EAP. If you are interested in joining this EAP, you can express interest through this form.

The setRelationships method allows you to create or update relationships in bulk. Relationships connect different types of objects (e.g., documents, teams, Jira issues) to represent how they relate to each other.

Method signature

1
2
setRelationships(request: BulkRelationshipsRequest): Promise<BulkRelationshipsResponse>

Parameter: request

  • Type: BulkRelationshipsRequest
  • Required: Yes
  • Description: The bulk relationships request containing relationships to create or update.
1
2
{
  relationships: RelationshipPayload[];
  connectionId: string;
}

Request Type: BulkRelationshipsRequest

1
2
{
  relationships: RelationshipPayload[];
  connectionId: string;
}

Response Type: BulkRelationshipsResponse

1
2
{
  success: boolean;
  results?: {
    [relationshipType: string]: RelationshipResponse[];
  };
  error?: string;
  originalError?: unknown;
}

RelationshipResponse Structure

1
2
{
  from: RelationshipEntity;           // Source entity
  to: RelationshipEntity;             // Target entity
  updateSequenceNumber: number;      // Update sequence number
  createdAt?: string;                 // ISO 8601 timestamp
  updatedAt?: string;                 // ISO 8601 timestamp
  // Note: 'type' is not included in the response - it's the key in the results object
}

RelationshipPayload Structure

1
2
{
  from: RelationshipEntity;           // Required - Source entity
  to: RelationshipEntity;             // Required - Target entity
  type: string;                       // Required - Relationship type identifier
  updateSequenceNumber?: number;      // Optional - Used for conflict resolution
  updatedAt?: string;                 // Optional - ISO 8601 timestamp
  createdAt?: string;                 // Optional - ISO 8601 timestamp
}

RelationshipEntity Structure

1
2
{
  type: string;                       // Required - Entity type (e.g., "atlassian:document", "issueId")
  value: RelationshipEntityValue;     // Required - Entity identifier
}

RelationshipEntityValue Structure

1
2
{
  entityId?: string;                  // For entities identified by entityId
  issueId?: string;                   // For Jira issues
  worklogId?: string;                 // For worklogs
  [key: string]: string | undefined;  // Additional identifier fields
}

Constraints

  • Maximum relationships per request: 100 (MAX_BULK_RELATIONSHIPS)
  • Required fields: from, to, type
  • Optional fields: updateSequenceNumber, updatedAt, createdAt

Usage examples

Basic relationship creation

1
2
import { graph, types } from '@forge/teamwork-graph';

const relationships: types.RelationshipPayload[] = [
  {
    from: {
      type: 'atlassian:team',
      value: {
        entityId: 'team-id-1'
      }
    },
    to: {
      type: 'issueWorklogId',
      value: {
        issueId: 'PT-1',
        worklogId: '10000'
      }
    },
    type: 'external-team-works-on-jira-work-item-worklog',
    updateSequenceNumber: 1,
    updatedAt: '2024-02-01T12:00:00.000Z',
    createdAt: '2024-01-10T10:00:00.000Z'
  }
];

const response = await graph.setRelationships({
  relationships: relationships,
  connectionId: 'your-connection-id'
});

if (response.success) {
  console.log('Relationships created:', response.results);
  // Results are grouped by relationship type
  if (response.results) {
    Object.entries(response.results).forEach(([relationshipType, relationships]) => {
      console.log(`${relationshipType}: ${relationships.length} relationships created`);
    });
  }
} else {
  console.error('Error:', response.error);
}

Multiple relationships

1
2
import { graph, types } from '@forge/teamwork-graph';

const relationships: types.RelationshipPayload[] = [
  {
    from: {
      type: 'atlassian:team',
      value: {
        entityId: 'team-id-1'
      }
    },
    to: {
      type: 'issueWorklogId',
      value: {
        issueId: 'PT-1',
        worklogId: '10000'
      }
    },
    type: 'external-team-works-on-jira-work-item-worklog',
    updateSequenceNumber: 1,
    updatedAt: '2024-02-01T12:00:00.000Z',
    createdAt: '2024-01-10T10:00:00.000Z'
  },
  {
    from: {
      type: 'atlassian:document',
      value: {
        entityId: 'doc-001'
      }
    },
    to: {
      type: 'issueId',
      value: {
        issueId: 'PT-2'
      }
    },
    type: 'external-document-works-on-jira-work-item',
    updateSequenceNumber: 1,
    updatedAt: '2024-02-01T12:00:00.000Z',
    createdAt: '2024-01-10T10:00:00.000Z'
  }
];

const response = await graph.setRelationships({
  relationships: relationships,
  connectionId: 'your-connection-id'
});

Request limits

  • Maximum relationships per request: 100
  • Minimum relationships per request: 1

Request validation

The method validates the following:

  • Must be an array: The relationships field must be a valid array.
  • Cannot be empty: The relationships array cannot be empty.
  • Maximum limit: Cannot exceed 100 relationships per request.
  • Required fields: Each relationship must have from, to, and type fields.

Error handling

Error messageDescription
relationships array cannot be emptyThe relationships array is empty.
Bulk relationship ingestion supports maximum 100 relationships. Received {count}The number of relationships per request has exceeded the maximum limit.
{field} is requiredA required field is missing from the relationship payload.
'type' is not valid.The relationship type is not valid or not registered.

Response

The method returns a promise that resolves to a BulkRelationshipsResponse object containing the ingestion results.

Success response

On success, results is an object where:

  • Keys are relationship types (e.g., "external-team-works-on-jira-work-item-worklog")
  • Values are arrays of successfully created relationships for that type

Example response:

1
2
{
  "success": true,
  "results": {
    "external-team-works-on-jira-work-item-worklog": [
      {
        "from": {
          "type": "atlassian:team",
          "value": {
            "entityId": "team-id-1"
          }
        },
        "to": {
          "type": "issueWorklogId",
          "value": {
            "issueId": "10001",
            "worklogId": "20002"
          }
        },
        "updateSequenceNumber": 1,
        "createdAt": "2011-08-01T21:32:44.882Z",
        "updatedAt": "2011-08-01T21:32:44.882Z"
      }
    ]
  }
}

Accessing response data

1
2
if (response.success && response.results) {
  // Iterate over relationship types
  Object.entries(response.results).forEach(([relationshipType, relationships]) => {
    console.log(`Relationship type: ${relationshipType}`);
    console.log(`Created ${relationships.length} relationships`);
    
    relationships.forEach(relationship => {
      console.log(`From: ${relationship.from.type} (${relationship.from.value.entityId})`);
      console.log(`To: ${relationship.to.type} (${relationship.to.value.issueId})`);
    });
  });
  
  // Access specific relationship type
  const teamWorklogRelationships = response.results['external-team-works-on-jira-work-item-worklog'];
  if (teamWorklogRelationships) {
    console.log(`Created ${teamWorklogRelationships.length} team-worklog relationships`);
  }
}

Relationship Types

Relationship types are string identifiers that describe the nature of the relationship. They typically follow a naming convention:

Format: external-{source-type}-{action}-{target-type}

Examples

  • external-team-works-on-jira-work-item-worklog - Team works on a Jira work item worklog
  • external-team-works-on-worklog - Team works on a worklog
  • external-document-works-on-jira-work-item - Document relates to a Jira work item

Note: Relationship types must be valid and may need to be registered or follow specific conventions defined by your connector configuration.

Entity Types

Common Entity Types

  • atlassian:document - Document entities
  • atlassian:team - Team entities
  • atlassian:work-item - Work item entities
  • issueId - Jira issue identifier
  • issueWorklogId - Jira issue worklog identifier

Entity Value Examples

For atlassian:document:

1
2
{
  type: 'atlassian:document',
  value: {
    entityId: 'doc-001'
  }
}

For issueId:

1
2
{
  type: 'issueId',
  value: {
    issueId: 'PT-1'
  }
}

For issueWorklogId:

1
2
{
  type: 'issueWorklogId',
  value: {
    issueId: '10001',
    worklogId: '20002'
  }
}

TypeScript Types Reference

All types are exported from @forge/teamwork-graph:

1
2
import { 
  types,
  graph 
} from '@forge/teamwork-graph';

// Available types:
// - types.RelationshipPayload
// - types.RelationshipEntity
// - types.RelationshipEntityValue
// - types.BulkRelationshipsRequest
// - types.BulkRelationshipsResponse

Constants

  • MAX_BULK_RELATIONSHIPS = 100 - Maximum number of relationships per bulk request

Best Practices

  1. Batch Processing: Process relationships in batches of up to 100 items
  2. Update Sequence Numbers: Use updateSequenceNumber for conflict resolution and tracking updates
  3. Timestamps: Include createdAt and updatedAt timestamps in ISO 8601 format
  4. Error Handling: Always check the success field and handle errors appropriately
  5. Relationship Types: Use descriptive, consistent naming for relationship types
  6. Connection ID: Always provide a valid connectionId for your connector

Rate this page: