OmniSocialsOmniSocials
DocumentationAPI reference
Help centerSupport
  • Documentation
  • API reference
Developers
  • Quickstart
  • API reference
  • SDKs
  • MCP server
  • CLI
For AI agents
  • Docs for AI agents
  • llms.txt
  • OpenAPI spec
  • Postman collection
Product
  • OmniSocials
  • Pricing
  • Changelog
  • Help center
Company
  • Support
  • Privacy policy
  • Terms of service

© 2026 OmniSocials

OmniSocials on GitHubOmniSocials on XOmniSocials on LinkedIn
Overview
Get started
SDKs
    Node.jsPythonGoRubyJavaPHP.NETRust
CLI
MCPDocs for AI agentsWebhooks
Guides
Platforms
Integrations
Migrate
Plans and billing
GlossaryChangelogAPI reference
SDKs

Java SDK reference: install, auth and methods

The official Java SDK. Java 11+, built on java.net.http.HttpClient, single dependency (Jackson), Jackson JsonNode responses with a fluent params builder.

This page is the reference. For an overview of the Java SDK, see omnisocials.com/sdk/java.

Install

Maven:

XMLMaven
<dependency> <groupId>com.omnisocials</groupId> <artifactId>omnisocials-java</artifactId> <version>0.12.0</version> </dependency>

Gradle:

Gradle
implementation "com.omnisocials:omnisocials-java:0.12.0"

Authentication

Java
OmniSocials client = OmniSocials.builder() .apiKey("omsk_live_...") .build();

Or OmniSocials.fromEnv() (reads OMNISOCIALS_API_KEY). A missing key throws AuthenticationException.

Create a post

Java
JsonNode res = client.posts().create(Params.builder() .put("content", "New drop this Friday") .put("channels", List.of("instagram", "facebook", "linkedin")) .put("scheduled_at", "2026-08-01T09:00:00Z") .put("media_urls", List.of("https://example.com/teaser.jpg")) .build()); JsonNode post = res.get("data"); System.out.println(post.get("id").asText() + " " + post.get("status").asText());

Any media_urls (or media_ids) entry can also be a map carrying per-media alt text (max 1500 chars), delivered to Mastodon, Bluesky, X (photos), Pinterest, Instagram (images), and LinkedIn (images):

Java
.put("media_urls", List.of(Params.of( "url", "https://example.com/teaser.jpg", "alt", "Red sneaker on a white background")))

Publish immediately:

Java
client.posts().createAndPublish(Params.builder() .put("content", "Going live right now") .put("channels", List.of("x", "bluesky")) .build());

Upload media

Java
JsonNode upload = client.media().uploadFromUrl(Params.builder() .put("url", "https://example.com/launch-video.mp4") .put("name", "launch-video-v2") .put("folder", "Campaigns") .build()); System.out.println(upload.get("data").get("id").asText()); System.out.println(upload.get("compatibility"));

Local files via multipart:

Java
import java.nio.file.Path; // From a path (filename and content type detected from the file) JsonNode res = client.media().upload(Path.of("photos/product.jpg"), Params.of("name", "product-hero")); // Or from bytes + filename byte[] bytes = java.nio.file.Files.readAllBytes(Path.of("photos/product.jpg")); client.media().upload(bytes, "product.jpg");

Analytics

Java
// One post's latest per-platform metrics JsonNode stats = client.analytics().post("post_id"); System.out.println(stats.get("data").get("platforms").path("instagram").path("metrics")); // Batch: up to 100 posts in one call JsonNode batch = client.analytics().posts(List.of("id1", "id2", "id3")); // or: client.analytics().posts("id1", "id2", "id3"); // Workspace-wide overview JsonNode overview = client.analytics().overview(Params.of("period", "30d")); System.out.println(overview.get("data").get("total_impressions").asLong()); // Account-level stats (followers etc) JsonNode accountStats = client.analytics().accounts(Params.of("platform", "instagram"));

Social Inbox

Read and answer DMs, comments and mentions from your connected accounts. The API key needs the opt-in inbox:read / inbox:write scopes. The lists use cursor pagination (cursor in, pagination.next_cursor out).

Java
JsonNode conversations = client.inbox().listConversations( Params.of("platform", "instagram", "unread", true)); String conversationId = conversations.get("data").get(0).get("conversation_id").asText(); JsonNode messages = client.inbox().getMessages(conversationId); client.inbox().reply(conversationId, Params.of("text", "Thanks for reaching out!")); client.inbox().markRead(conversationId); // Comment moderation: hide (hide(messageId, false) unhides) or delete String messageId = messages.get("data").get(0).get("id").asText(); client.inbox().hide(messageId); client.inbox().deleteMessage(messageId);

inbox().next() hands out the next conversation that still needs an answer, with the thread and the post it belongs to. On a comment thread, pass message_id so the reply goes under the comment you answer and not under the newest comment on the post.

Java
JsonNode next = client.inbox().next().get("data"); while (next != null && !next.isNull()) { JsonNode message = next.get("message"); if (!next.get("reply_window").get("open").asBoolean()) { // An Instagram/Facebook DM past Meta's 24-hour window: answer it in the app client.inbox().markRead(message.get("conversation_id").asText()); next = client.inbox().next().get("data"); continue; } JsonNode reply = client.inbox().reply( message.get("conversation_id").asText(), Params.of( "text", "Thanks! DM sent.", "message_id", message.get("id").asText(), "include_next", true)); next = reply.get("next"); }

See the Social Inbox guide for the platforms, the reply rules and the error codes.

Pinterest product tags

Tag products on a Pin so people can shop the items in the image. List the product Pins of the connected Pinterest account, then pass up to 24 of their Pin ids as product_tags in the pinterest map of the post. Only product Pins of your own account can be tagged; products of other merchants cannot.

Java
JsonNode result = client.pinterest().listProducts(); if (result.has("error")) { System.err.println(result.get("error").get("code").asText()); } else { List<String> productTags = new ArrayList<>(); for (JsonNode product : result.get("products")) { if (productTags.size() < 3) { productTags.add(product.get("pin_id").asText()); } } client.posts().create(Params.builder() .put("content", "Our summer picks") .put("channels", List.of("pinterest")) .put("media_urls", List.of("https://example.com/summer-look.jpg")) .put("scheduled_at", "2026-08-01T09:00:00Z") .put("pinterest", Params.of("board_id", "1234567890", "product_tags", productTags)) .build()); }

The list answers with HTTP 200 in both cases: products on success, or an error object (pinterest_not_connected, pinterest_catalog_access_required, platform_error) when it could not be read. It reads the Pinterest catalog when the connection has catalog access (given one time in the OmniSocials composer: Pinterest options, Add products, Connect catalog), else the account's own Pins. The tags are added right after the Pin is published. A product that Pinterest refuses never fails the post: the post then carries pinterest.product_tags_result with the tagged and the skipped Pin ids. client.pinterest().validateProduct(id) checks one Pin id or Pin link before you post. On posts().update() the pinterest map replaces the stored one, so leave product_tags out to remove the tags.

Verify webhooks

Spring Boot:

Java
import com.fasterxml.jackson.databind.JsonNode; import com.omnisocials.Webhooks; import com.omnisocials.errors.WebhookVerificationException; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; @RestController public class OmniSocialsWebhookController { private final String secret = System.getenv("OMNISOCIALS_WEBHOOK_SECRET"); @PostMapping("/omnisocials/webhook") public ResponseEntity<Void> handle( @RequestBody String rawBody, // Spring gives you the raw body as a String @RequestHeader("X-OmniSocials-Signature") String signature) { JsonNode event; try { event = Webhooks.verifySignature(rawBody, signature, secret, 300); } catch (WebhookVerificationException e) { return ResponseEntity.badRequest().build(); } switch (event.get("type").asText()) { case "post.published": System.out.println("Published: " + event.get("data").get("post_id").asText()); break; case "post.failed": System.err.println("Failed: " + event.get("data").get("post_id").asText()); break; case "post.rejected": System.err.println("Rejected: " + event.get("data").get("post_id").asText() + " " + event.get("data").get("approval").get("reason").asText()); break; default: break; } return ResponseEntity.ok().build(); } }

Events: post.scheduled, post.published, post.failed, post.approved and post.rejected. The two approval events carry data.approval with status, decided_by (the approver's user id) and reason (null on post.approved). To read the full review of a post (steps, approvers, the rejection reason and the comment thread), call client.posts().getApproval(id).

Errors

All exceptions extend OmniSocialsException (unchecked) and live in com.omnisocials.errors. ApiException exposes getStatus(), getCode(), getMessage(), and getBody(). Types: ValidationException (400/422), AuthenticationException (401), PermissionDeniedException (403), NotFoundException (404), RateLimitException (429, getRetryAfter()), ServerException (5xx), ApiConnectionException, WebhookVerificationException.

Java
import com.omnisocials.errors.*; try { client.posts().create(Params.of("content", "Hi", "channels", List.of("instagram"))); } catch (RateLimitException e) { System.out.println("Rate limited, retry in " + e.getRetryAfter() + "s"); } catch (ValidationException e) { System.err.println("Bad request (" + e.getCode() + "): " + e.getMessage()); System.err.println(e.getBody()); } catch (ApiConnectionException e) { System.err.println("Network problem: " + e.getMessage()); } catch (ApiException e) { System.err.println("API error " + e.getStatus() + " (" + e.getCode() + "): " + e.getMessage()); }

Configuration

Java
import java.time.Duration; OmniSocials client = OmniSocials.builder() .apiKey("omsk_live_...") .baseUrl("https://api.omnisocials.com/v1") // default .timeout(Duration.ofSeconds(30)) // per-request timeout (default 30s) .maxRetries(2) // retries on 429 / 5xx / network errors (default 2) .build();

Notes

  • Params via Params.builder().put(...).build() or Params.of(k, v, ...); unlike Map.of, null values are allowed and serialize to JSON null
  • Responses are Jackson JsonNode
  • Webhook verification uses MessageDigest.isEqual (constant time)
  • Source: github.com/OmniSocials/omnisocials-java
Last modified on October 22, 2026
RubyPHP
On this page
  • Install
  • Authentication
  • Create a post
  • Upload media
  • Analytics
  • Social Inbox
  • Pinterest product tags
  • Verify webhooks
  • Errors
  • Configuration
  • Notes
Java
Java
Java
Java
Java
Java
Java
Java
Java
Java
Java
Java
Java