A friend list API describes relationships between accounts, not simply a collection of profile cards. A pending invitation, an accepted connection, a removed relationship, and a blocked account have different meanings. A careful design keeps those states explicit and decides who may see each relationship in each context.
This guide proposes an application-owned relationship model. It does not promise access to a third-party social network's private friend data, and ListAPI.com does not operate a social graph. Start with the relationships your own application is authorized to manage. Do not assume that knowing a profile identifier grants permission to retrieve that person's connections.
Choose the relationship type before the endpoint
A mutual friendship is different from a one-way follow, a saved contact, or membership in a group. Define which relationship the application supports and what creates it. For mutual friendship, an invitation and acceptance may be separate operations. A following model may be directed, with one account following another without a reciprocal relationship.
Avoid using one generic array for every connection type. A person can follow someone, share a group with them, and still not be their friend. Keep those relationships distinct so visibility and notification rules can differ. This also prevents a later feature from interpreting a weak connection as authorization to reveal information intended only for accepted friends.
Give the relationship its own identity
Use a durable relationship_id and explicit participant identifiers. For mutual relationships, define how the pair is normalized so the same two accounts cannot accidentally create duplicate accepted friendships through simultaneous requests. The implementation should enforce the intended uniqueness rule, rather than relying on the interface to prevent a second click.
Keep the current state separate from the event history. An invitation can be sent, withdrawn, resent, accepted, and later removed. A history of authorized actions can help explain the current state without turning every event into a separate visible friendship. Retain only the history needed for the application's purpose and define how account deletion affects that history.
Design a state machine people can understand
Choose a small set of states and allowed transitions. For example, a pending request can be accepted by the recipient or withdrawn by the sender. An accepted relationship can be removed by either participant. Define what happens when requests cross, when an invitation is repeated, and when the recipient has already blocked the sender.
Do not expose every internal state directly to every participant. A privacy-preserving interface may need to use a generic unavailable response instead of revealing that a person blocked someone. The exact presentation is a product decision, but it should be deliberate. A status code or error message should not disclose more relationship information than the normal interface allows.
Authorize every relationship operation
A request should be evaluated in the context of the authenticated actor, the target relationship, the requested action, and the applicable visibility rules. A user who can read their own friend list should not automatically be able to read someone else's. Similarly, knowing the identifier of a pending request should not allow an unrelated account to accept it.
The OWASP authorization guidance recommends least privilege, denial by default, and permission checks on every request. Those principles provide a useful foundation for this model. Apply them to list retrieval, direct relationship retrieval, exports, and background jobs. The application-specific design in this guide is a recommendation, not a claim that one generic access check makes every social feature safe.
Keep blocking separate from ordinary removal
Removing a friendship and blocking an account can have different effects. Removal may end access to friend-only information while still allowing future invitations. Blocking may also restrict contact, visibility, or discovery according to your application's rules. Store the blocking relationship separately when it needs its own direction and lifecycle.
Define how blocking interacts with existing invitations, notifications, and shared views. A blocked person's old activity should not remain exposed through an overlooked suggestion endpoint if the intended policy hides it. At the same time, avoid promising that blocking erases messages or screenshots already held by another person. Describe the actual controls the application enforces rather than implying universal retraction.
Build visibility into list queries
A friend's existence, display name, or presence in a particular group can be sensitive. Apply visibility rules before generating the response, including counts and pagination metadata. A public count of hidden relationships can reveal information even when the individual rows are removed. Decide what the viewer is allowed to learn from the entire response, not only from each profile field.
Keep profile visibility separate from relationship visibility. A public profile does not necessarily imply a public friend list. A private relationship may still permit both participants to see it while excluding everyone else. Model those choices explicitly and test them with viewers who have different relationships to the same account.
Make invitations resistant to accidental repetition
An interrupted request can leave the sender unsure whether an invitation was created. Define repeat behavior so retrying the same action does not produce several invitations or notifications. For an API you control, use a stable operation identifier or another documented idempotency mechanism. Enforce relationship-state constraints in the trusted application layer, not just in the button's disabled state.
Separate the relationship change from notification delivery. The friendship request can be recorded successfully even if an email notification is delayed. Track those outcomes independently so retrying notification delivery does not recreate the invitation. This makes recovery more predictable and gives support operators a clearer explanation of what actually happened.
Keep discovery narrower than data collection
A friend suggestion feature should begin with an explicit purpose and a permitted data source. Do not quietly upload an address book or infer relationships from unrelated private information merely to populate a suggestion panel. The fact that two accounts share a field does not necessarily mean either person wants that connection revealed.
Give users understandable controls over discovery. Consider whether an account can be found by an address, whether mutual connections are visible, and whether suggestions can expose membership in a private community. Keep the matching evidence out of broad logs and avoid returning raw personal identifiers when a less revealing internal reference will do.
Test the graph from several viewpoints
Create a small test graph with accepted friends, pending invitations, a blocked account, a private profile, and an unrelated viewer. For every action, inspect the result as the sender, recipient, an ordinary friend, and an outsider. Test list retrieval and direct identifier requests separately. A relationship hidden in one view should not reappear through another route with weaker checks.
Include simultaneous invitations, repeated acceptance, account deletion, and role changes. Verify that stale notifications do not imply a relationship still exists after it has ended. Write expected outcomes in ordinary language before implementing the endpoints. That exercise often reveals product ambiguities that cannot be solved by adding another Boolean field.
A safe first relationship feature
A sensible first release can support deliberate invitations, acceptance, removal, blocking, and a private list visible only to its owner. Add public friend lists, suggestions, and cross-application imports only after their audience rules are explicit. A smaller feature with predictable boundaries is easier for people to understand and for developers to test.
The core principle is to treat a relationship as a permission-sensitive object with a lifecycle. Preserve the difference between contact, invitation, friendship, and block. When each action has a clear actor and each response has a defined audience, a friend list API can support genuine connection without turning the social graph into an unrestricted directory.
Official reference. OWASP: authorization cheat sheet. This reference supports the provider-specific distinction discussed in the guide. The broader workflow recommendations are ListAPI.com’s editorial design guidance. Reference reviewed September 11, 2026.
For a compact starting point, explore the Friend List API field model. The API basics guide explains the shared vocabulary used across these workflows.



