The Adobe Enterprise Automation platform provides a GraphQL API that offers a flexible and efficient way to query and manipulate data. GraphQL allows clients to request exactly the data they need, reducing over-fetching and improving performance.
- GraphQL Endpoint:
http://localhost:4000/graphql - WebSocket Endpoint (for subscriptions):
ws://localhost:4000/graphql - GraphQL Playground: Available in development at
http://localhost:4000/graphql
All GraphQL requests require authentication via JWT tokens in the Authorization header:
Authorization: Bearer <your-jwt-token>For WebSocket subscriptions, pass the token in connection params:
const wsClient = new WebSocketClient({
url: 'ws://localhost:4000/graphql',
connectionParams: {
authToken: 'your-jwt-token'
}
});Represents an Adobe Creative Cloud user in the system.
type User {
id: ID!
email: String!
firstName: String!
lastName: String!
department: String!
products: [String!]!
status: UserStatus!
createdAt: Date!
lastLogin: Date
licenses: [License!]!
usageStats: UserUsageStats
}Represents a software license allocation.
type License {
id: ID!
product: String!
type: LicenseType!
assignedTo: User
assignedAt: Date
expiresAt: Date
status: LicenseStatus!
cost: Float
}Represents an organizational department.
type Department {
name: String!
userCount: Int!
licenseCount: Int!
totalCost: Float!
users: [User!]!
licenses: [License!]!
}query GetUser($email: String!) {
userByEmail(email: $email) {
id
email
firstName
lastName
department
products
status
licenses {
id
product
status
expiresAt
}
}
}query ListUsers($limit: Int, $offset: Int) {
users(
pagination: { limit: $limit, offset: $offset }
) {
edges {
node {
id
email
firstName
lastName
department
status
}
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
totalCount
}
}query SearchUsers($search: String!) {
users(filter: { search: $search }) {
edges {
node {
id
email
firstName
lastName
department
}
}
totalCount
}
}query GetUtilization($product: String) {
licenseUtilization(product: $product) {
total
used
available
utilizationPercentage
byDepartment {
department
used
total
percentage
}
byProduct {
product
used
total
percentage
}
}
}query GetPredictions($daysAhead: Int!) {
licensePredictions(daysAhead: $daysAhead) {
product
department
date
predictedUsage
confidenceLower
confidenceUpper
trend
}
}query GetCostAnalysis {
costAnalysis {
totalCost
costByDepartment {
department
cost
userCount
averageCostPerUser
}
costByProduct {
product
cost
licenseCount
averageCostPerLicense
}
trend
projectedCost
savingsOpportunity
}
}mutation CreateUser($input: UserCreateInput!) {
createUser(input: $input) {
id
email
firstName
lastName
department
products
status
}
}Variables:
{
"input": {
"email": "john.doe@company.com",
"firstName": "John",
"lastName": "Doe",
"department": "Marketing",
"products": ["Creative Cloud", "Acrobat Pro"]
}
}mutation UpdateUser($id: ID!, $input: UserUpdateInput!) {
updateUser(id: $id, input: $input) {
id
email
department
status
}
}mutation AssignLicense($userId: ID!, $product: String!) {
assignLicense(userId: $userId, product: $product) {
id
product
assignedTo {
email
}
assignedAt
status
}
}mutation BulkCreateUsers($users: [UserCreateInput!]!) {
bulkCreateUsers(users: $users) {
created {
id
email
}
failed {
email
error
}
totalProcessed
successCount
failureCount
}
}mutation RunOptimization($dryRun: Boolean) {
optimizeLicenses(dryRun: $dryRun) {
optimized
licensesReclaimed
estimatedSavings
recommendations
}
}subscription OnUserUpdated($userId: ID) {
userUpdated(userId: $userId) {
id
email
status
department
}
}subscription OnLicenseAssigned {
licenseAssigned {
id
product
assignedTo {
email
}
assignedAt
}
}subscription OnOptimizationCompleted {
optimizationCompleted {
optimized
licensesReclaimed
estimatedSavings
}
}GraphQL errors follow a standard format:
{
"errors": [
{
"message": "User not found",
"extensions": {
"code": "NOT_FOUND",
"stacktrace": "..." // Only in development
},
"path": ["user"],
"locations": [{"line": 2, "column": 3}]
}
]
}UNAUTHENTICATED: Missing or invalid authenticationFORBIDDEN: Insufficient permissionsNOT_FOUND: Requested resource not foundBAD_USER_INPUT: Invalid input dataINTERNAL_SERVER_ERROR: Server-side error
The API uses cursor-based pagination for large result sets:
query PaginatedUsers($cursor: String, $limit: Int) {
users(
pagination: {
limit: $limit
offset: 0
sortBy: "email"
sortOrder: ASC
}
) {
edges {
node { ... }
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
totalCount
}
}input UserFilterInput {
email: String
department: String
status: UserStatus
product: String
search: String
}input PaginationInput {
limit: Int
offset: Int
sortBy: String
sortOrder: SortOrder
}
enum SortOrder {
ASC
DESC
}-
Request Only What You Need: GraphQL allows you to specify exactly which fields you want.
-
Use Fragments for Reusable Fields:
fragment UserBasicInfo on User {
id
email
firstName
lastName
}
query GetUsers {
users {
edges {
node {
...UserBasicInfo
department
}
}
}
}-
Batch Similar Queries: Combine multiple queries in a single request.
-
Handle Errors Gracefully: Always check for errors in responses.
-
Use Variables: Don't hardcode values in queries.
-
Implement Caching: Take advantage of GraphQL's predictable responses.
The GraphQL API implements rate limiting:
- Anonymous: 100 requests per hour
- Authenticated: 5000 requests per hour
- Admin: 10000 requests per hour
- Navigate to
http://localhost:4000/graphql - Add your JWT token in HTTP headers:
{
"Authorization": "Bearer your-jwt-token"
}- Use the documentation explorer to browse the schema
- Test queries in the editor with auto-completion
- View real-time results and errors
import { ApolloClient, InMemoryCache, gql } from '@apollo/client';
const client = new ApolloClient({
uri: 'http://localhost:4000/graphql',
cache: new InMemoryCache(),
headers: {
authorization: `Bearer ${token}`
}
});
// Query example
const GET_USERS = gql`
query GetUsers {
users {
edges {
node {
id
email
}
}
}
}
`;
client.query({ query: GET_USERS })
.then(result => console.log(result));from gql import gql, Client
from gql.transport.aiohttp import AIOHTTPTransport
transport = AIOHTTPTransport(
url="http://localhost:4000/graphql",
headers={"Authorization": f"Bearer {token}"}
)
client = Client(transport=transport, fetch_schema_from_transport=True)
query = gql("""
query GetUsers {
users {
edges {
node {
id
email
}
}
}
}
""")
result = client.execute(query)- Use DataLoader: Batch and cache database requests
- Implement Field-Level Caching: Cache expensive computations
- Optimize N+1 Queries: Use batch loading for related data
- Limit Query Depth: Prevent deeply nested queries
- Use Persisted Queries: Store frequently used queries
- Query Depth Limiting: Maximum query depth is limited to 10
- Query Complexity Analysis: Complex queries may be rejected
- Rate Limiting: Prevents abuse and ensures fair usage
- Field-Level Authorization: Some fields require specific permissions
- Input Validation: All inputs are validated and sanitized
For issues or questions about the GraphQL API:
- Check the schema documentation in GraphQL Playground
- Review error messages and codes
- Contact the development team
- Submit issues to the project repository